aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2017-10-31 15:44:45 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-31 20:09:25 +0000
commitbef063af14d0608a5c40fe4473fbfaf1db591603 (patch)
tree9bd7cb9535b0e6f0d37182ba468b2c25ebab0140
parent43fd6d848583b554316c84956df0d5908402981c (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.gn1
-rw-r--r--docs/SkBitmap_Reference.bmh2
-rw-r--r--docs/SkMatrix_Reference.bmh58
-rw-r--r--docs/catalogHeader.txt9
-rw-r--r--docs/catalogTrailer.txt217
-rw-r--r--site/user/api/SkBitmap_Reference.md2
-rw-r--r--site/user/api/SkMatrix_Reference.md66
-rw-r--r--tools/bookmaker/bookmaker.cpp79
-rw-r--r--tools/bookmaker/bookmaker.h76
-rw-r--r--tools/bookmaker/cataloger.cpp143
-rw-r--r--tools/bookmaker/fiddleParser.cpp149
-rw-r--r--tools/bookmaker/parserCommon.cpp2
12 files changed, 668 insertions, 136 deletions
diff --git a/BUILD.gn b/BUILD.gn
index a0c8973312..3cf235236c 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -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);