diff options
author | 2017-10-31 15:44:45 -0400 | |
---|---|---|
committer | 2017-10-31 20:09:25 +0000 | |
commit | bef063af14d0608a5c40fe4473fbfaf1db591603 (patch) | |
tree | 9bd7cb9535b0e6f0d37182ba468b2c25ebab0140 | |
parent | 43fd6d848583b554316c84956df0d5908402981c (diff) |
cataloger
Docs-Preview: https://skia.org/?cl=64900
Bug: skia:6898
Change-Id: Ifbaf909854680a88060f16b1559863cc124aaa7a
Reviewed-on: https://skia-review.googlesource.com/64900
Commit-Queue: Cary Clark <caryclark@skia.org>
Reviewed-by: Cary Clark <caryclark@skia.org>
-rw-r--r-- | BUILD.gn | 1 | ||||
-rw-r--r-- | docs/SkBitmap_Reference.bmh | 2 | ||||
-rw-r--r-- | docs/SkMatrix_Reference.bmh | 58 | ||||
-rw-r--r-- | docs/catalogHeader.txt | 9 | ||||
-rw-r--r-- | docs/catalogTrailer.txt | 217 | ||||
-rw-r--r-- | site/user/api/SkBitmap_Reference.md | 2 | ||||
-rw-r--r-- | site/user/api/SkMatrix_Reference.md | 66 | ||||
-rw-r--r-- | tools/bookmaker/bookmaker.cpp | 79 | ||||
-rw-r--r-- | tools/bookmaker/bookmaker.h | 76 | ||||
-rw-r--r-- | tools/bookmaker/cataloger.cpp | 143 | ||||
-rw-r--r-- | tools/bookmaker/fiddleParser.cpp | 149 | ||||
-rw-r--r-- | tools/bookmaker/parserCommon.cpp | 2 |
12 files changed, 668 insertions, 136 deletions
@@ -1289,6 +1289,7 @@ if (skia_enable_tools) { test_app("bookmaker") { sources = [ "tools/bookmaker/bookmaker.cpp", + "tools/bookmaker/cataloger.cpp", "tools/bookmaker/fiddleParser.cpp", "tools/bookmaker/includeParser.cpp", "tools/bookmaker/includeWriter.cpp", diff --git a/docs/SkBitmap_Reference.bmh b/docs/SkBitmap_Reference.bmh index 75cd57ed99..78677655e8 100644 --- a/docs/SkBitmap_Reference.bmh +++ b/docs/SkBitmap_Reference.bmh @@ -21,7 +21,7 @@ Declaring SkBitmap const prevents altering Image_Info: the Bitmap height, width, and so on cannot change. It does not affect Pixel_Ref: a caller may write its pixels. Declaring SkBitmap const affects Bitmap configuration, not its contents. -Bitmap is not thread safe. Each thread must have its own copy if Bitmap fields, +Bitmap is not thread safe. Each thread must have its own copy of Bitmap fields, although threads may share the underlying pixel array. #Topic Row_Bytes diff --git a/docs/SkMatrix_Reference.bmh b/docs/SkMatrix_Reference.bmh index e0d3987d17..54d21c8fff 100644 --- a/docs/SkMatrix_Reference.bmh +++ b/docs/SkMatrix_Reference.bmh @@ -47,6 +47,7 @@ improve performance. Matrix is not thread safe unless getType is called first. # Concat # Returns the concatenation of Matrix pair. ## # I # Returns a reference to a const identity Matrix. ## # InvalidMatrix # Returns a reference to a const invalid Matrix. ## +# MakeAll # Constructs all nine values. ## # MakeRectToRect # Constructs from source Rect to destination Rect. ## # MakeScale # Constructs from scale in x and y. ## # MakeTrans # Constructs from translate in x and y. ## @@ -221,6 +222,53 @@ for (int i = 0; i < 4; ++i) { # ------------------------------------------------------------------------------ +#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, + SkScalar skewY, SkScalar scaleY, SkScalar transY, + SkScalar pers0, SkScalar pers1, SkScalar pers2) + + +Sets Matrix to: + +#Code +#Literal +| scaleX skewX transX | +| skewY scaleY transY | +| pers0 pers1 pers2 | +## + +#Param scaleX horizontal scale factor ## +#Param skewX horizontal skew factor ## +#Param transX horizontal translation ## +#Param skewY vertical skew factor ## +#Param scaleY vertical scale factor ## +#Param transY vertical translation ## +#Param pers0 input x perspective factor ## +#Param pers1 input y perspective factor ## +#Param pers2 perspective scale factor ## + +#Return Matrix constructed from parameters ## + +#Example + SkPaint p; + p.setAntiAlias(true); + p.setTextSize(64); + for (SkScalar sx : { -1, 1 } ) { + for (SkScalar sy : { -1, 1 } ) { + SkAutoCanvasRestore autoRestore(canvas, true); + SkMatrix m = SkMatrix::MakeAll(sx, 1, 128, 0, sy, 128, 0, 0, 1); + canvas->concat(m); + canvas->drawString("K", 0, 0, p); + } + } +## + +#SeeAlso setAll set9 postConcat preConcat + +## + + +# ------------------------------------------------------------------------------ + #Enum TypeMask #Code @@ -551,7 +599,7 @@ paint.setTextSize(48); canvas->drawString(string, 0, source.bounds().height() + 48, paint); ## -#SeeAlso setAll set9 +#SeeAlso setAll set9 MakeAll ## @@ -1267,7 +1315,7 @@ for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) { } ## -#SeeAlso getPerspX set setAll set9 +#SeeAlso getPerspX set setAll set9 MakeAll #Method ## @@ -1294,7 +1342,7 @@ for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) { } ## -#SeeAlso getPerspY set setAll set9 +#SeeAlso getPerspY set setAll set9 MakeAll #Method ## @@ -1338,7 +1386,7 @@ Sets all values from parameters. Sets matrix to: } ## -#SeeAlso set9 +#SeeAlso set9 MakeAll #Method ## @@ -1402,7 +1450,7 @@ canvas->concat(m); canvas->drawBitmap(source, 0, 0); ## -#SeeAlso setAll get9 +#SeeAlso setAll get9 MakeAll #Method ## diff --git a/docs/catalogHeader.txt b/docs/catalogHeader.txt new file mode 100644 index 0000000000..0ca0568cd2 --- /dev/null +++ b/docs/catalogHeader.txt @@ -0,0 +1,9 @@ +<!DOCTYPE html> + +<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta charset="utf-8" /> + <title></title> + +<script type="text/javascript"> + diff --git a/docs/catalogTrailer.txt b/docs/catalogTrailer.txt new file mode 100644 index 0000000000..0bfb8b7584 --- /dev/null +++ b/docs/catalogTrailer.txt @@ -0,0 +1,217 @@ + +var canvas +var context +var getFromWeb = true +var mouseDown = false +var scale = .6 +var outset = 15 +var columnWidth = 256 +var maxHeight = 256 +var lastLink = null +var lastLinkStr = null +var labelback = {} +var loadedImages = 0 +var images = {} +var imagesLength = 0; + +function recContains(rec, value) { + if (!value.length)
+ return 0
+ var lc = value.toLowerCase()
+ if (rec.name.toLowerCase().indexOf(lc) >= 0)
+ return 1
+ if (rec.code.toLowerCase().indexOf(lc) >= 0)
+ return 2
+ return 3
+} + +function setLink(recstr) { + var under + var link = recstr + if (!link.startsWith("Sk")) {
+ under = link.indexOf('_') + link = link.substring(under + 1)
+ } + under = link.lastIndexOf('_') + var len = link.length + if (under == len - 2) {
+ var letter = link[len - 1] + if ('a' <= letter && letter <= 'z') {
+ link = link.substr(0, len - 2)
+ } else if ('0' <= letter && letter <= '9') {
+ link = link.substr(0, len - 2)
+ }
+ } + lastLinkStr = link
+} + +function showLink() {
+ var link = lastLink.file + '#' + lastLinkStr
+ context.save()
+ context.font = "normal 16px Arial"; + labelback.w = Math.max(labelback.w, context.measureText(link).width + 8)
+ context.beginPath()
+ context.rect(labelback.x, labelback.y, labelback.w, labelback.h)
+ context.fillStyle = "rgba(232,180,220, 1)"
+ context.fill()
+ context.fillStyle = "rgba(64,32,48, 1)"
+ context.fillText(link, labelback.x + 4, labelback.y + 16)
+ context.restore()
+} + +function imageIterator(callout, state) {
+ var row = outset + 30 + var column = outset + for (var recstr in pngs) { + var rec = pngs[recstr] + var contains = recContains(rec, input.value) + if (3 == contains)
+ continue;
+ var height = rec.height < maxHeight ? rec.height : maxHeight + if (callout(state, column, row, height, contains, recstr)) + break; + row += height + outset + if (row >= canvas.height / scale) { + row = 0 + column += columnWidth + outset + if (column >= canvas.width / scale) { + break + } + } + } +} + +function handleMouseOver(event) { + var callout = function(state, column, row, height, contains, recstr) { + if (state.x >= column && state.x <= column + columnWidth && + state.y >= row && state.y <= row + height) { + document.body.style.cursor = "pointer" + lastLink = pngs[recstr] + setLink(recstr) + showLink() + return true + } + return false + } + var state = { + x: (event.clientX - 5) / scale, + y: (event.clientY - 7) / scale + } + document.body.style.cursor = "" + lastLink = null + imageIterator(callout, state) +} + +function handleMouseClick() { + if (null != lastLink) { + var link = 'https://skia.org/user/api/' + lastLink.file + '#' + lastLinkStr + window.location = link + } +} + +function doKeyPress(evt) {
+ idiv.style.height = 20 + input.focus() +} + +function drawImage(hash, x, y, w, h, contains) {
+ context.save() + context.transform(scale, 0, 0, scale, 0, 0) + context.save() + context.beginPath() + context.rect(x, y, w, h) + context.clip() + context.drawImage(images[hash], x, y) + context.restore() + context.beginPath() + context.rect(x, y, w, h) + context.strokeStyle = 1 == contains ? "red" : "black" + context.stroke() + context.restore() +} + +function draw() { + var callout = function(state, column, row, height, contains, recstr) { + drawImage(pngs[recstr].hash, column, row, columnWidth, height, contains) + return false
+ } + imageIterator(callout, null) +} + +function sleep(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+}
+
+async function redraw() {
+ context.strokeStyle = "white"
+ context.beginPath() + context.fillStyle = "white" + context.rect(0, 30, canvas.width, canvas.height) + context.fill() + context.rect((256 + outset) * scale, 0, canvas.width, 30) + context.fill()
+ for (var image in images) {
+ image.drawn = false
+ }
+ do {
+ draw();
+ if (loadedImages >= imagesLength)
+ break;
+ console.debug(" loadedImages:" + loadedImages + " imagesLength:" + imagesLength)
+ await sleep(1000);
+ } while (true)
+} + +function resize() { + setSize() + redraw() +} + +function setSize() { + canvas.width = window.innerWidth - 20 + canvas.height = window.innerHeight - 20 + labelback.x = 0 + labelback.y = canvas.height - 20 + labelback.w = 0 + labelback.h = 20 +} + +function loadImages() {
+ for (var recstr in pngs) {
+ var rec = pngs[recstr] + var image = new Image() + images[rec.hash] = image
+ if (getFromWeb) + image.src = 'https://fiddle.skia.org/i/' + image.src += rec.hash + '_raster.png' + image.onload = function () {
+ loadedImages += 1
+ }
+ imagesLength += 1;
+ }
+} + +function start() {
+ loadImages() + window.addEventListener('keypress', doKeyPress, true); + window.addEventListener('keydown', doKeyPress, true); + canvas = document.getElementById('canvas') + context = canvas.getContext('2d') + resize() +} + +</script> +</head> + +<body onLoad="start()" onresize="resize()"> +<div style="height:0" id="idiv">
+<input type="text" id="input" onkeypress="redraw()" onkeydown="redraw()"/>
+</div> +<canvas id="canvas" width="750" height="500" +onmousedown="mouseDown = true" +onmouseup="mouseDown = false" +onmousemove="handleMouseOver(event)" +onclick="handleMouseClick()" +></canvas > +</body> +</html> diff --git a/site/user/api/SkBitmap_Reference.md b/site/user/api/SkBitmap_Reference.md index 4182c50733..df514533e9 100644 --- a/site/user/api/SkBitmap_Reference.md +++ b/site/user/api/SkBitmap_Reference.md @@ -21,7 +21,7 @@ Declaring <a href="#SkBitmap">SkBitmap</a> const prevents altering <a href="#Inf and so on cannot change. It does not affect <a href="undocumented#Pixel_Ref">Pixel Ref</a>: a caller may write its pixels. Declaring <a href="#SkBitmap">SkBitmap</a> const affects <a href="#Bitmap">Bitmap</a> configuration, not its contents. -<a href="#Bitmap">Bitmap</a> is not thread safe. Each thread must have its own copy if <a href="#Bitmap">Bitmap</a> fields, +<a href="#Bitmap">Bitmap</a> is not thread safe. Each thread must have its own copy of <a href="#Bitmap">Bitmap</a> fields, although threads may share the underlying pixel array. # <a name="Row_Bytes"></a> Row Bytes diff --git a/site/user/api/SkMatrix_Reference.md b/site/user/api/SkMatrix_Reference.md index 2fd97b0976..6c9b893794 100644 --- a/site/user/api/SkMatrix_Reference.md +++ b/site/user/api/SkMatrix_Reference.md @@ -39,6 +39,7 @@ improve performance. <a href="#Matrix">Matrix</a> is not thread safe unless <a h | <a href="#SkMatrix_Concat">Concat</a> | Returns the concatenation of <a href="#Matrix">Matrix</a> pair. | | <a href="#SkMatrix_I">I</a> | Returns a reference to a const identity <a href="#Matrix">Matrix</a>. | | <a href="#SkMatrix_InvalidMatrix">InvalidMatrix</a> | Returns a reference to a const invalid <a href="#Matrix">Matrix</a>. | +| <a href="#SkMatrix_MakeAll">MakeAll</a> | Constructs all nine values. | | <a href="#SkMatrix_MakeRectToRect">MakeRectToRect</a> | Constructs from source <a href="SkRect_Reference#Rect">Rect</a> to destination <a href="SkRect_Reference#Rect">Rect</a>. | | <a href="#SkMatrix_MakeScale">MakeScale</a> | Constructs from scale in x and y. | | <a href="#SkMatrix_MakeTrans">MakeTrans</a> | Constructs from translate in x and y. | @@ -227,6 +228,61 @@ vertical translation</td> --- +<a name="SkMatrix_MakeAll"></a> +## MakeAll + +<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0"> +static SkMatrix SK_WARN_UNUSED_RESULT MakeAll(SkScalar scaleX, SkScalar skewX, + SkScalar transX, SkScalar skewY, + SkScalar scaleY, SkScalar transY, + SkScalar pers0, SkScalar pers1, + SkScalar pers2) +</pre> + +Sets <a href="#Matrix">Matrix</a> to: + +<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0"> +| scaleX skewX transX | +| skewY scaleY transY | +| pers0 pers1 pers2 |</pre> + +### Parameters + +<table> <tr> <td><a name="SkMatrix_MakeAll_scaleX"> <code><strong>scaleX </strong></code> </a></td> <td> +horizontal scale factor</td> + </tr> <tr> <td><a name="SkMatrix_MakeAll_skewX"> <code><strong>skewX </strong></code> </a></td> <td> +horizontal skew factor</td> + </tr> <tr> <td><a name="SkMatrix_MakeAll_transX"> <code><strong>transX </strong></code> </a></td> <td> +horizontal translation</td> + </tr> <tr> <td><a name="SkMatrix_MakeAll_skewY"> <code><strong>skewY </strong></code> </a></td> <td> +vertical skew factor</td> + </tr> <tr> <td><a name="SkMatrix_MakeAll_scaleY"> <code><strong>scaleY </strong></code> </a></td> <td> +vertical scale factor</td> + </tr> <tr> <td><a name="SkMatrix_MakeAll_transY"> <code><strong>transY </strong></code> </a></td> <td> +vertical translation</td> + </tr> <tr> <td><a name="SkMatrix_MakeAll_pers0"> <code><strong>pers0 </strong></code> </a></td> <td> +input x perspective factor</td> + </tr> <tr> <td><a name="SkMatrix_MakeAll_pers1"> <code><strong>pers1 </strong></code> </a></td> <td> +input y perspective factor</td> + </tr> <tr> <td><a name="SkMatrix_MakeAll_pers2"> <code><strong>pers2 </strong></code> </a></td> <td> +perspective scale factor</td> + </tr> +</table> + +### Return Value + +<a href="#Matrix">Matrix</a> constructed from parameters + +### Example + +<div><fiddle-embed name="6bad83b64de9266e323c29d550e04188"></fiddle-embed></div> + +### See Also + +<a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_set9">set9</a> <a href="#SkMatrix_postConcat">postConcat</a> <a href="#SkMatrix_preConcat">preConcat</a> + +--- + ## <a name="SkMatrix_TypeMask"></a> Enum SkMatrix::TypeMask <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0"> @@ -568,7 +624,7 @@ true if <a href="#Matrix">Matrix</a> is in most general form ### See Also -<a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_set9">set9</a> +<a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_set9">set9</a> <a href="#SkMatrix_MakeAll">MakeAll</a> --- @@ -1338,7 +1394,7 @@ perspective factor</td> ### See Also -<a href="#SkMatrix_getPerspX">getPerspX</a> <a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_set9">set9</a> +<a href="#SkMatrix_getPerspX">getPerspX</a> <a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_set9">set9</a> <a href="#SkMatrix_MakeAll">MakeAll</a> --- @@ -1365,7 +1421,7 @@ perspective factor</td> ### See Also -<a href="#SkMatrix_getPerspY">getPerspY</a> <a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_set9">set9</a> +<a href="#SkMatrix_getPerspY">getPerspY</a> <a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_set9">set9</a> <a href="#SkMatrix_MakeAll">MakeAll</a> --- @@ -1414,7 +1470,7 @@ perspective scale factor to store</td> ### See Also -<a href="#SkMatrix_set9">set9</a> +<a href="#SkMatrix_set9">set9</a> <a href="#SkMatrix_MakeAll">MakeAll</a> --- @@ -1491,7 +1547,7 @@ nine <a href="#Scalar">Scalar</a> values</td> ### See Also -<a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_get9">get9</a> +<a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_get9">get9</a> <a href="#SkMatrix_MakeAll">MakeAll</a> --- diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp index e0694071e2..ca60084100 100644 --- a/tools/bookmaker/bookmaker.cpp +++ b/tools/bookmaker/bookmaker.cpp @@ -11,13 +11,14 @@ #include "SkOSPath.h" DEFINE_string2(bmh, b, "", "Path to a *.bmh file or a directory."); +DEFINE_bool2(catalog, c, false, "Write example catalog.htm. (Requires -b -f -r)"); DEFINE_string2(examples, e, "", "File of fiddlecli input, usually fiddle.json (For now, disables -r -f -s)"); DEFINE_string2(fiddle, f, "", "File of fiddlecli output, usually fiddleout.json."); DEFINE_string2(include, i, "", "Path to a *.h file or a directory."); DEFINE_bool2(hack, k, false, "Do a find/replace hack to update all *.bmh files. (Requires -b)"); DEFINE_bool2(stdout, o, false, "Write file out to standard out."); DEFINE_bool2(populate, p, false, "Populate include from bmh. (Requires -b -i)"); -DEFINE_string2(ref, r, "", "Resolve refs and write bmh_*.md files to path. (Requires -b)"); +DEFINE_string2(ref, r, "", "Resolve refs and write bmh_*.md files to path. (Requires -b -f)"); DEFINE_string2(spellcheck, s, "", "Spell-check [once, all, mispelling]. (Requires -b)"); DEFINE_string2(tokens, t, "", "Directory to write bmh from include. (Requires -i)"); DEFINE_bool2(crosscheck, x, false, "Check bmh against includes. (Requires -b -i)"); @@ -214,7 +215,7 @@ void Definition::setCanonicalFiddle() { fFiddle = normalized_name(result); } -bool Definition::exampleToScript(string* result) const { +bool Definition::exampleToScript(string* result, ExampleOptions exampleOptions) const { bool hasFiddle = true; const Definition* platform = this->hasChild(MarkType::kPlatform); if (platform) { @@ -307,19 +308,37 @@ bool Definition::exampleToScript(string* result) const { code += "}"; } string example = "\"" + normalizedName + "\": {\n"; - example += " \"code\": \"" + code + "\",\n"; - example += " \"options\": {\n"; - example += " \"width\": " + widthStr + ",\n"; - example += " \"height\": " + heightStr + ",\n"; - example += " \"source\": " + imageStr + ",\n"; - example += " \"srgb\": false,\n"; - example += " \"f16\": false,\n"; - example += " \"textOnly\": " + textOutStr + ",\n"; - example += " \"animated\": false,\n"; - example += " \"duration\": 0\n"; - example += " },\n"; - example += " \"fast\": true\n"; - example += "}"; + size_t nameStart = fFileName.find("\\", 0); + SkASSERT(string::npos != nameStart); + string baseFile = fFileName.substr(nameStart + 1, fFileName.length() - nameStart - 5); + if (ExampleOptions::kText == exampleOptions) { + example += " \"code\": \"" + code + "\",\n"; + example += " \"hash\": \"" + fHash + "\",\n"; + example += " \"file\": \"" + baseFile + "\",\n"; + example += " \"name\": \"" + fName + "\","; + } else { + example += " \"code\": \"" + code + "\",\n"; + if (ExampleOptions::kPng == exampleOptions) { + example += " \"width\": " + widthStr + ",\n"; + example += " \"height\": " + heightStr + ",\n"; + example += " \"hash\": \"" + fHash + "\",\n"; + example += " \"file\": \"" + baseFile + "\",\n"; + example += " \"name\": \"" + fName + "\"\n"; + example += "}"; + } else { + example += " \"options\": {\n"; + example += " \"width\": " + widthStr + ",\n"; + example += " \"height\": " + heightStr + ",\n"; + example += " \"source\": " + imageStr + ",\n"; + example += " \"srgb\": false,\n"; + example += " \"f16\": false,\n"; + example += " \"textOnly\": " + textOutStr + ",\n"; + example += " \"animated\": false,\n"; + example += " \"duration\": 0\n"; + example += " },\n"; + example += " \"fast\": true"; + } + } *result = example; return true; } @@ -754,6 +773,7 @@ bool Definition::nextMethodParam(TextParser* methodParser, const char** nextEndP } bool ParserCommon::parseFile(const char* fileOrPath, const char* suffix) { +// this->reset(); if (!sk_isdir(fileOrPath)) { if (!this->parseFromFile(fileOrPath)) { SkDebugf("failed to parse %s\n", fileOrPath); @@ -1398,10 +1418,12 @@ bool BmhParser::collectExternals() { static bool dump_examples(FILE* fiddleOut, const Definition& def, bool* continuation) { if (MarkType::kExample == def.fMarkType) { string result; - if (!def.exampleToScript(&result)) { + if (!def.exampleToScript(&result, Definition::ExampleOptions::kAll)) { return false; } if (result.length() > 0) { + result += "\n"; + result += "}"; if (*continuation) { fprintf(fiddleOut, ",\n"); } else { @@ -2245,6 +2267,11 @@ int main(int argc, char** const argv) { SkCommandLineFlags::PrintUsage(); return 1; } + if ((FLAGS_bmh.isEmpty() || FLAGS_fiddle.isEmpty() || FLAGS_ref.isEmpty()) && FLAGS_catalog) { + SkDebugf("-c requires -b -f -r\n"); + SkCommandLineFlags::PrintUsage(); + return 1; + } if (FLAGS_bmh.isEmpty() && !FLAGS_examples.isEmpty()) { SkDebugf("-e requires -b\n"); SkCommandLineFlags::PrintUsage(); @@ -2289,6 +2316,7 @@ int main(int argc, char** const argv) { return 1; } if (!FLAGS_bmh.isEmpty()) { + bmhParser.reset(); if (!bmhParser.parseFile(FLAGS_bmh[0], ".bmh")) { return -1; } @@ -2327,11 +2355,26 @@ int main(int argc, char** const argv) { done = true; } } - FiddleParser fparser(&bmhParser); - if (!done && !FLAGS_fiddle.isEmpty() && FLAGS_examples.isEmpty()) { + if (!done && !FLAGS_catalog && !FLAGS_fiddle.isEmpty() && FLAGS_examples.isEmpty()) { + FiddleParser fparser(&bmhParser); + if (!fparser.parseFile(FLAGS_fiddle[0], ".txt")) { + return -1; + } + } + if (!done && FLAGS_catalog && FLAGS_examples.isEmpty()) { + Catalog fparser(&bmhParser); + fparser.fDebugOut = FLAGS_stdout; + if (!fparser.openCatalog(FLAGS_bmh[0], FLAGS_ref[0])) { + return -1; + } if (!fparser.parseFile(FLAGS_fiddle[0], ".txt")) { return -1; } + if (!fparser.closeCatalog()) { + return -1; + } + bmhParser.fWroteOut = true; + done = true; } if (!done && !FLAGS_ref.isEmpty() && FLAGS_examples.isEmpty()) { MdOut mdOut(bmhParser); diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h index f5f53ff7ab..167fcb24f7 100644 --- a/tools/bookmaker/bookmaker.h +++ b/tools/bookmaker/bookmaker.h @@ -682,6 +682,12 @@ public: kYes }; + enum class ExampleOptions { + kText, + kPng, + kAll + }; + enum class MethodType { kNone, kConstructor, @@ -785,7 +791,7 @@ public: bool crossCheck2(const Definition& includeToken) const; bool crossCheck(const Definition& includeToken) const; bool crossCheckInside(const char* start, const char* end, const Definition& includeToken) const; - bool exampleToScript(string* result) const; + bool exampleToScript(string* result, ExampleOptions ) const; string extractText(TrimExtract trimExtract) const { string result; @@ -1768,7 +1774,10 @@ public: const ParentPair* fPrev; }; - IncludeWriter() : IncludeParser() {} + IncludeWriter() : IncludeParser() { + this->reset(); + } + ~IncludeWriter() override {} bool contentFree(int size, const char* data) const { @@ -1843,14 +1852,41 @@ private: typedef IncludeParser INHERITED; }; -class FiddleParser : public ParserCommon { -public: - FiddleParser(BmhParser* bmh) : ParserCommon() - , fBmhParser(bmh) { +class FiddleBase : public ParserCommon { +protected: + FiddleBase(BmhParser* bmh) : ParserCommon() + , fBmhParser(bmh) + , fContinuation(false) + , fTextOut(false) + , fPngOut(false) + { this->reset(); } + void reset() override { + INHERITED::resetCommon(); + } + Definition* findExample(const string& name) const; + bool parseFiddles(); + virtual bool pngOut(Definition* example) = 0; + virtual bool textOut(Definition* example, const char* stdOutStart, + const char* stdOutEnd) = 0; + + BmhParser* fBmhParser; // must be writable; writes example hash + string fFullName; + bool fContinuation; + bool fTextOut; + bool fPngOut; +private: + typedef ParserCommon INHERITED; +}; + +class FiddleParser : public FiddleBase { +public: + FiddleParser(BmhParser* bmh) : FiddleBase(bmh) { + fTextOut = true; + } bool parseFromFile(const char* path) override { if (!INHERITED::parseSetup(path)) { @@ -1859,16 +1895,34 @@ public: return parseFiddles(); } - void reset() override { - INHERITED::resetCommon(); +private: + bool pngOut(Definition* example) override { + return true; } + bool textOut(Definition* example, const char* stdOutStart, + const char* stdOutEnd) override; + + typedef FiddleBase INHERITED; +}; + +class Catalog : public FiddleBase { +public: + Catalog(BmhParser* bmh) : FiddleBase(bmh) {} + + bool appendFile(const string& path); + bool closeCatalog(); + bool openCatalog(const char* inDir, const char* outDir); + + bool parseFromFile(const char* path) override ; private: - bool parseFiddles(); + bool pngOut(Definition* example) override; + bool textOut(Definition* example, const char* stdOutStart, + const char* stdOutEnd) override; - BmhParser* fBmhParser; // must be writable; writes example hash + string fDocsDir; - typedef ParserCommon INHERITED; + typedef FiddleBase INHERITED; }; class HackParser : public ParserCommon { diff --git a/tools/bookmaker/cataloger.cpp b/tools/bookmaker/cataloger.cpp new file mode 100644 index 0000000000..c757b6ac9f --- /dev/null +++ b/tools/bookmaker/cataloger.cpp @@ -0,0 +1,143 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "bookmaker.h" + +#include "SkOSFile.h" +#include "SkOSPath.h" + +bool Catalog::appendFile(const string& path) { + FILE* file = fopen(path.c_str(), "r"); + if (!file) { + SkDebugf("could not append %s\n", path.c_str()); + return false; + } + fseek(file, 0L, SEEK_END); + int sz = (int) ftell(file); + rewind(file); + char* buffer = new char[sz]; + memset(buffer, ' ', sz); + fread(buffer, 1, sz, file); + fclose(file); + this->writeBlock(sz, buffer); + return true; +} + +bool Catalog::openCatalog(const char* inDir, const char* outDir) { + fDocsDir = inDir; + if ('/' != fDocsDir.back()) { + fDocsDir += '/'; + } + string outie = outDir; + if ('/' != outie.back()) { + outie += '/'; + } + fFullName = outie + "catalog.htm"; + fOut = fopen(fFullName.c_str(), "wb"); + if (!fOut) { + SkDebugf("could not open output file %s\n", fFullName.c_str()); + return false; + } + fContinuation = false; + if (!appendFile(fDocsDir + "catalogHeader.txt")) { + return false; + } + this->lf(1); + return true; +} + +bool Catalog::closeCatalog() { + if (fOut) { + this->lf(1); + this->writeString("}"); + this->lf(1); + if (!appendFile(fDocsDir + "catalogTrailer.txt")) { + return false; + } + this->lf(1); + this->writePending(); + fclose(fOut); + SkDebugf("wrote %s\n", fFullName.c_str()); + fOut = nullptr; + } + return true; +} + +bool Catalog::parseFromFile(const char* path) { + if (!INHERITED::parseSetup(path)) { + return false; + } + fIndent = 4; + this->writeString("var text = {"); + this->lf(1); + fTextOut = true; + TextParser::Save save(this); + if (!parseFiddles()) { + return false; + } + this->lf(1); + this->writeString("}"); + this->lf(2); + this->writeString("var pngs = {"); + fTextOut = false; + fPngOut = true; + save.restore(); + fContinuation = false; + return parseFiddles(); +} + +bool Catalog::pngOut(Definition* example) { + string result; + if (!example->exampleToScript(&result, Definition::ExampleOptions::kPng)) { + return false; + } + if (result.length() > 0) { + if (fContinuation) { + this->writeString(","); + this->lf(1); + } else { + fContinuation = true; + } + this->writeBlock(result.size(), result.c_str()); + } + return true; +} + +bool Catalog::textOut(Definition* example, const char* stdOutStart, + const char* stdOutEnd) { + string result; + if (!example->exampleToScript(&result, Definition::ExampleOptions::kText)) { + return false; + } + if (result.length() > 0) { + if (fContinuation) { + this->writeString(","); + this->lf(1); + } else { + fContinuation = true; + } + fIndent = 8; + this->writeBlock(result.size(), result.c_str()); + this->lf(1); + this->writeString("\"stdout\": \""); + size_t pos = 0; + size_t len = stdOutEnd - stdOutStart; + string example; + while ((size_t) pos < len) { + example += '"' == stdOutStart[pos] ? "\\\"" : + '\\' == stdOutStart[pos] ? "\\\\" : + string(&stdOutStart[pos], 1); + ++pos; + } + this->writeBlock(example.length(), example.c_str()); + this->writeString("\""); + this->lf(1); + fIndent = 4; + this->writeString("}"); + } + return true; +} diff --git a/tools/bookmaker/fiddleParser.cpp b/tools/bookmaker/fiddleParser.cpp index 3361543301..faf551006f 100644 --- a/tools/bookmaker/fiddleParser.cpp +++ b/tools/bookmaker/fiddleParser.cpp @@ -20,7 +20,7 @@ static Definition* find_fiddle(Definition* def, const string& name) { return nullptr; } -Definition* FiddleParser::findExample(const string& name) const { +Definition* FiddleBase::findExample(const string& name) const { for (const auto& topic : fBmhParser->fTopicMap) { if (topic.second->fParent) { continue; @@ -33,7 +33,7 @@ Definition* FiddleParser::findExample(const string& name) const { return nullptr; } -bool FiddleParser::parseFiddles() { +bool FiddleBase::parseFiddles() { if (!this->skipExact("{\n")) { return false; } @@ -110,50 +110,15 @@ bool FiddleParser::parseFiddles() { } } while (!this->eof() && this->next()); const char* stdOutEnd = fChar; - if (example) { - bool foundStdOut = false; - for (auto& textOut : example->fChildren) { - if (MarkType::kStdOut != textOut->fMarkType) { - continue; - } - foundStdOut = true; - bool foundVolatile = false; - for (auto& stdOutChild : textOut->fChildren) { - if (MarkType::kVolatile == stdOutChild->fMarkType) { - foundVolatile = true; - break; - } - } - TextParser bmh(textOut); - EscapeParser fiddle(stdOutStart, stdOutEnd); - do { - bmh.skipWhiteSpace(); - fiddle.skipWhiteSpace(); - const char* bmhEnd = bmh.trimmedLineEnd(); - const char* fiddleEnd = fiddle.trimmedLineEnd(); - ptrdiff_t bmhLen = bmhEnd - bmh.fChar; - SkASSERT(bmhLen > 0); - ptrdiff_t fiddleLen = fiddleEnd - fiddle.fChar; - SkASSERT(fiddleLen > 0); - if (bmhLen != fiddleLen) { - if (!foundVolatile) { - bmh.reportError("mismatched stdout len\n"); - } - } else if (strncmp(bmh.fChar, fiddle.fChar, fiddleLen)) { - if (!foundVolatile) { - bmh.reportError("mismatched stdout text\n"); - } - } - bmh.skipToLineStart(); - fiddle.skipToLineStart(); - } while (!bmh.eof() && !fiddle.eof()); - if (!foundStdOut) { - bmh.reportError("bmh %s missing stdout\n"); - } else if (!bmh.eof() || !fiddle.eof()) { - if (!foundVolatile) { - bmh.reportError("%s mismatched stdout eof\n"); - } - } + if (example && fTextOut) { + if (!this->textOut(example, stdOutStart, stdOutEnd)) { + return false; + } + } + } else { + if (example && fPngOut) { + if (!this->pngOut(example)) { + return false; } } } @@ -170,58 +135,54 @@ bool FiddleParser::parseFiddles() { return false; } } -#if 0 - // compare the text output with the expected output in the markup tree - this->skipToSpace(); - SkASSERT(' ' == fChar[0]); - this->next(); - const char* nameLoc = fChar; - this->skipToNonAlphaNum(); - const char* nameEnd = fChar; - string name(nameLoc, nameEnd - nameLoc); - const Definition* example = this->findExample(name); - if (!example) { - return this->reportError<bool>("missing stdout name"); - } - SkASSERT(':' == fChar[0]); - this->next(); - this->skipSpace(); - const char* stdOutLoc = fChar; - do { - this->skipToLineStart(); - } while (!this->eof() && !this->startsWith("fiddles.htm:")); - const char* stdOutEnd = fChar; - for (auto& textOut : example->fChildren) { - if (MarkType::kStdOut != textOut->fMarkType) { - continue; + return true; +} + +bool FiddleParser::textOut(Definition* example, const char* stdOutStart, + const char* stdOutEnd) { + bool foundStdOut = false; + for (auto& textOut : example->fChildren) { + if (MarkType::kStdOut != textOut->fMarkType) { + continue; + } + foundStdOut = true; + bool foundVolatile = false; + for (auto& stdOutChild : textOut->fChildren) { + if (MarkType::kVolatile == stdOutChild->fMarkType) { + foundVolatile = true; + break; } - TextParser bmh(textOut); - TextParser fiddle(fFileName, stdOutLoc, stdOutEnd, fLineCount); - do { - bmh.skipWhiteSpace(); - fiddle.skipWhiteSpace(); - const char* bmhEnd = bmh.trimmedLineEnd(); - const char* fiddleEnd = fiddle.trimmedLineEnd(); - ptrdiff_t bmhLen = bmhEnd - bmh.fChar; - SkASSERT(bmhLen > 0); - ptrdiff_t fiddleLen = fiddleEnd - fiddle.fChar; - SkASSERT(fiddleLen > 0); - if (bmhLen != fiddleLen) { - return this->reportError<bool>("mismatched stdout len"); - } - if (strncmp(bmh.fChar, fiddle.fChar, fiddleLen)) { - return this->reportError<bool>("mismatched stdout text"); - } - bmh.skipToLineStart(); - fiddle.skipToLineStart(); - } while (!bmh.eof() && !fiddle.eof()); - if (!bmh.eof() || (!fiddle.eof() && !fiddle.startsWith("</pre>"))) { - return this->reportError<bool>("mismatched stdout eof"); + } + TextParser bmh(textOut); + EscapeParser fiddle(stdOutStart, stdOutEnd); + do { + bmh.skipWhiteSpace(); + fiddle.skipWhiteSpace(); + const char* bmhEnd = bmh.trimmedLineEnd(); + const char* fiddleEnd = fiddle.trimmedLineEnd(); + ptrdiff_t bmhLen = bmhEnd - bmh.fChar; + SkASSERT(bmhLen > 0); + ptrdiff_t fiddleLen = fiddleEnd - fiddle.fChar; + SkASSERT(fiddleLen > 0); + if (bmhLen != fiddleLen) { + if (!foundVolatile) { + bmh.reportError("mismatched stdout len\n"); + } + } else if (strncmp(bmh.fChar, fiddle.fChar, fiddleLen)) { + if (!foundVolatile) { + bmh.reportError("mismatched stdout text\n"); } - break; + } + bmh.skipToLineStart(); + fiddle.skipToLineStart(); + } while (!bmh.eof() && !fiddle.eof()); + if (!foundStdOut) { + bmh.reportError("bmh %s missing stdout\n"); + } else if (!bmh.eof() || !fiddle.eof()) { + if (!foundVolatile) { + bmh.reportError("%s mismatched stdout eof\n"); } } } -#endif return true; } diff --git a/tools/bookmaker/parserCommon.cpp b/tools/bookmaker/parserCommon.cpp index fbfcbae728..7a6f71f7ed 100644 --- a/tools/bookmaker/parserCommon.cpp +++ b/tools/bookmaker/parserCommon.cpp @@ -13,7 +13,7 @@ static void debug_out(int len, const char* data) { } bool ParserCommon::parseSetup(const char* path) { - this->reset(); +// this->reset(); sk_sp<SkData> data = SkData::MakeFromFileName(path); if (nullptr == data.get()) { SkDebugf("%s missing\n", path); |