fix bookmaker

add error handling if bmh has #Populate
but include has been marked deprecated

TBR=reed@google.com

Bug: skia:
Change-Id: I1a577bbf95ebe4f5fe46ea2c6a1e1f10f6b8e684
Reviewed-on: https://skia-review.googlesource.com/c/177062
Reviewed-by: Cary Clark <caryclark@skia.org>
Commit-Queue: Cary Clark <caryclark@skia.org>
Auto-Submit: Cary Clark <caryclark@skia.org>
This commit is contained in:
Cary Clark 2018-12-12 13:32:56 -05:00 committed by Skia Commit-Bot
parent ef3d04e796
commit 05c1dcfd35
4 changed files with 281 additions and 315 deletions

View File

@ -3399,54 +3399,6 @@ Text_Path describes the geometry of Glyphs used to draw text.
#Subtopic Text_Path ## #Subtopic Text_Path ##
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
#Subtopic Text_Intercepts
#Line # advanced underline, strike through ##
Text_Intercepts describe the intersection of drawn text Glyphs with a pair
of lines parallel to the text advance. Text_Intercepts permits creating a
underline that skips Descenders.
#Method int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
SkScalar* intervals) const
#In Text_Intercepts
#Line # returns where lines intersect Text_Blob; underlines ##
#Populate
#Example
#Height 143
void draw(SkCanvas* canvas) {
SkFont font;
font.setSize(120);
SkPoint textPos = { 20, 110 };
int len = 3;
SkTextBlobBuilder textBlobBuilder;
const SkTextBlobBuilder::RunBuffer& run =
textBlobBuilder.allocRun(font, len, textPos.fX, textPos.fY);
run.glyphs[0] = 10;
run.glyphs[1] = 20;
run.glyphs[2] = 30;
sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
SkPaint paint;
SkScalar bounds[] = { 116, 134 };
int count = paint.getTextBlobIntercepts(blob.get(), bounds, nullptr);
std::vector<SkScalar> intervals;
intervals.resize(count);
(void) paint.getTextBlobIntercepts(blob.get(), bounds, &intervals.front());
canvas->drawTextBlob(blob.get(), 0, 0, paint);
paint.setColor(0xFFFF7777);
SkScalar x = textPos.fX;
for (int i = 0; i < count; i+= 2) {
canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
x = intervals[i + 1];
}
canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
}
##
##
#Subtopic Text_Intercepts ##
# ------------------------------------------------------------------------------
#Method bool nothingToDraw() const #Method bool nothingToDraw() const
#In Utility #In Utility

View File

@ -1,104 +1,111 @@
#Topic Text_Blob #Topic Text_Blob
#Alias Text_Blob_Reference ## #Alias Text_Blob_Reference ##
#Class SkTextBlob #Class SkTextBlob
#Code #Code
#Populate #Populate
## ##
SkTextBlob combines multiple text runs into an immutable container. Each text SkTextBlob combines multiple text runs into an immutable container. Each text
run consists of Glyphs, Paint, and position. Only parts of Paint related to run consists of Glyphs, Paint, and position. Only parts of Paint related to
fonts and text rendering are used by run. fonts and text rendering are used by run.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
#Method const SkRect& bounds() const #Method const SkRect& bounds() const
#In Property #In Property
#Line # returns conservative bounding box ## #Line # returns conservative bounding box ##
#Populate #Populate
#Example #Example
#Height 70 #Height 70
SkTextBlobBuilder textBlobBuilder; SkTextBlobBuilder textBlobBuilder;
const char bunny[] = "/(^x^)\\"; const char bunny[] = "/(^x^)\\";
const int len = sizeof(bunny) - 1; const int len = sizeof(bunny) - 1;
uint16_t glyphs[len]; uint16_t glyphs[len];
SkPaint paint; SkPaint paint;
paint.textToGlyphs(bunny, len, glyphs); paint.textToGlyphs(bunny, len, glyphs);
paint.setTextEncoding(kGlyphID_SkTextEncoding); paint.setTextEncoding(kGlyphID_SkTextEncoding);
SkFont font; SkFont font;
int runs[] = { 3, 1, 3 }; int runs[] = { 3, 1, 3 };
SkPoint textPos = { 20, 50 }; SkPoint textPos = { 20, 50 };
int glyphIndex = 0; int glyphIndex = 0;
for (auto runLen : runs) { for (auto runLen : runs) {
font.setSize(1 == runLen ? 20 : 50); font.setSize(1 == runLen ? 20 : 50);
paint.setTextSize(1 == runLen ? 20 : 50); paint.setTextSize(1 == runLen ? 20 : 50);
const SkTextBlobBuilder::RunBuffer& run = const SkTextBlobBuilder::RunBuffer& run =
textBlobBuilder.allocRun(font, runLen, textPos.fX, textPos.fY); textBlobBuilder.allocRun(font, runLen, textPos.fX, textPos.fY);
memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen); memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr); textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
glyphIndex += runLen; glyphIndex += runLen;
} }
sk_sp<const SkTextBlob> blob = textBlobBuilder.make(); sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
canvas->drawTextBlob(blob.get(), 0, 0, paint); canvas->drawTextBlob(blob.get(), 0, 0, paint);
paint.setStyle(SkPaint::kStroke_Style); paint.setStyle(SkPaint::kStroke_Style);
canvas->drawRect(blob->bounds(), paint); canvas->drawRect(blob->bounds(), paint);
## ##
#SeeAlso SkPath::getBounds #SeeAlso SkPath::getBounds
#Method ## #Method ##
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
#Method uint32_t uniqueID() const #Method uint32_t uniqueID() const
#In Property #In Property
#Line # returns identifier for Text_Blob ## #Line # returns identifier for Text_Blob ##
#Populate #Populate
#Example #Example
for (int index = 0; index < 2; ++index) { for (int index = 0; index < 2; ++index) {
SkTextBlobBuilder textBlobBuilder; SkTextBlobBuilder textBlobBuilder;
const char bunny[] = "/(^x^)\\"; const char bunny[] = "/(^x^)\\";
const int len = sizeof(bunny) - 1; const int len = sizeof(bunny) - 1;
uint16_t glyphs[len]; uint16_t glyphs[len];
SkPaint paint; SkPaint paint;
paint.textToGlyphs(bunny, len, glyphs); paint.textToGlyphs(bunny, len, glyphs);
paint.setTextEncoding(kGlyphID_SkTextEncoding); paint.setTextEncoding(kGlyphID_SkTextEncoding);
paint.setTextScaleX(0.5); paint.setTextScaleX(0.5);
SkFont font; SkFont font;
font.setScaleX(0.5); font.setScaleX(0.5);
int runs[] = { 3, 1, 3 }; int runs[] = { 3, 1, 3 };
SkPoint textPos = { 20, 50 }; SkPoint textPos = { 20, 50 };
int glyphIndex = 0; int glyphIndex = 0;
for (auto runLen : runs) { for (auto runLen : runs) {
font.setSize(1 == runLen ? 20 : 50); font.setSize(1 == runLen ? 20 : 50);
paint.setTextSize(1 == runLen ? 20 : 50); paint.setTextSize(1 == runLen ? 20 : 50);
const SkTextBlobBuilder::RunBuffer& run = const SkTextBlobBuilder::RunBuffer& run =
textBlobBuilder.allocRun(font, runLen, textPos.fX, textPos.fY); textBlobBuilder.allocRun(font, runLen, textPos.fX, textPos.fY);
memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen); memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr); textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
glyphIndex += runLen; glyphIndex += runLen;
} }
sk_sp<const SkTextBlob> blob = textBlobBuilder.make(); sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
paint.reset(); paint.reset();
canvas->drawTextBlob(blob.get(), 0, 0, paint); canvas->drawTextBlob(blob.get(), 0, 0, paint);
std::string id = "unique ID:" + std::to_string(blob->uniqueID()); std::string id = "unique ID:" + std::to_string(blob->uniqueID());
canvas->drawString(id.c_str(), 30, blob->bounds().fBottom + 15, paint); canvas->drawString(id.c_str(), 30, blob->bounds().fBottom + 15, paint);
canvas->translate(blob->bounds().fRight + 10, 0); canvas->translate(blob->bounds().fRight + 10, 0);
} }
## ##
#SeeAlso SkRefCnt #SeeAlso SkRefCnt
#Method ## #Method ##
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
#Subtopic Text_Intercepts
#Line # advanced underline, strike through ##
Text_Intercepts describe the intersection of drawn text Glyphs with a pair
of lines parallel to the text advance. Text_Intercepts permits creating a
underline that skips Descenders.
#Method int getIntercepts(const SkScalar bounds[2], SkScalar intervals[], #Method int getIntercepts(const SkScalar bounds[2], SkScalar intervals[],
const SkPaint* paint = nullptr) const; const SkPaint* paint = nullptr) const;
#In Utility #In Text_Intercepts
#Line # returns where lines intersect Text_Blob; underlines ## #Line # returns where lines intersect Text_Blob; underlines ##
#Populate #Populate
@ -132,169 +139,171 @@ for (int index = 0; index < 2; ++index) {
canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint); canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
} }
## ##
#Method ## #Method ##
# ------------------------------------------------------------------------------ #Subtopic Text_Intercepts ##
#Method static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font, # ------------------------------------------------------------------------------
SkTextEncoding encoding = kUTF8_SkTextEncoding)
#In Constructors #Method static sk_sp<SkTextBlob> MakeFromText(const void* text, size_t byteLength, const SkFont& font,
#Line # constructs Text_Blob with one run ## SkTextEncoding encoding = kUTF8_SkTextEncoding)
#In Constructors
Creates Text_Blob with a single run. text meaning depends on Text_Encoding; #Line # constructs Text_Blob with one run ##
by default, text is encoded as UTF-8.
Creates Text_Blob with a single run. text meaning depends on Text_Encoding;
font contains attributes used to define the run text: #font_metrics#. by default, text is encoded as UTF-8.
#Param text character code points or Glyphs drawn ## font contains attributes used to define the run text: #font_metrics#.
#Param byteLength byte length of text array ##
#Param font text size, typeface, text scale, and so on, used to draw ## #Param text character code points or Glyphs drawn ##
#Param encoding one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding, #Param byteLength byte length of text array ##
kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding #Param font text size, typeface, text scale, and so on, used to draw ##
## #Param encoding one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
#Return Text_Blob constructed from one run ## ##
#Example #Return Text_Blob constructed from one run ##
#Height 24
SkFont font; #Example
font.setSize(24); #Height 24
SkPaint canvasPaint; SkFont font;
canvasPaint.setColor(SK_ColorBLUE); // respected font.setSize(24);
canvasPaint.setTextSize(2); // ignored SkPaint canvasPaint;
sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, font); canvasPaint.setColor(SK_ColorBLUE); // respected
canvas->drawTextBlob(blob, 20, 20, canvasPaint); canvasPaint.setTextSize(2); // ignored
## sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, font);
canvas->drawTextBlob(blob, 20, 20, canvasPaint);
#SeeAlso MakeFromString SkTextBlobBuilder ##
## #SeeAlso MakeFromString SkTextBlobBuilder
# ------------------------------------------------------------------------------ ##
#Method static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font, # ------------------------------------------------------------------------------
SkTextEncoding encoding = kUTF8_SkTextEncoding)
#In Constructors #Method static sk_sp<SkTextBlob> MakeFromString(const char* string, const SkFont& font,
#Line # constructs Text_Blob with one run ## SkTextEncoding encoding = kUTF8_SkTextEncoding)
#In Constructors
Creates Text_Blob with a single run. string meaning depends on Text_Encoding; #Line # constructs Text_Blob with one run ##
by default, string is encoded as UTF-8.
Creates Text_Blob with a single run. string meaning depends on Text_Encoding;
font contains Font_Metrics used to define the run text: #font_metrics#. by default, string is encoded as UTF-8.
#Param string character code points or Glyphs drawn ## font contains Font_Metrics used to define the run text: #font_metrics#.
#Param font text size, typeface, text scale, and so on, used to draw ##
#Param encoding one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding, #Param string character code points or Glyphs drawn ##
kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding #Param font text size, typeface, text scale, and so on, used to draw ##
## #Param encoding one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
#Return Text_Blob constructed from one run ## ##
#Example #Return Text_Blob constructed from one run ##
#Height 24
SkFont font; #Example
font.setSize(24); #Height 24
SkPaint canvasPaint; SkFont font;
canvasPaint.setColor(SK_ColorBLUE); // respected font.setSize(24);
canvasPaint.setTextSize(2); // ignored SkPaint canvasPaint;
sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString("Hello World", font); canvasPaint.setColor(SK_ColorBLUE); // respected
canvas->drawTextBlob(blob, 20, 20, canvasPaint); canvasPaint.setTextSize(2); // ignored
## sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString("Hello World", font);
canvas->drawTextBlob(blob, 20, 20, canvasPaint);
#SeeAlso MakeFromText SkTextBlobBuilder ##
## #SeeAlso MakeFromText SkTextBlobBuilder
# ------------------------------------------------------------------------------ ##
#Method size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const # ------------------------------------------------------------------------------
#In Utility
#Line # writes Text_Blob to memory ## #Method size_t serialize(const SkSerialProcs& procs, void* memory, size_t memory_size) const
#Populate #In Utility
#Line # writes Text_Blob to memory ##
#Example #Populate
#Height 64
###$ #Example
$Function #Height 64
#include "SkSerialProcs.h" ###$
$$ $Function
$$$# #include "SkSerialProcs.h"
SkFont blobFont; $$
blobFont.setSize(24); $$$#
sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobFont); SkFont blobFont;
char storage[2048]; blobFont.setSize(24);
size_t used = blob->serialize(SkSerialProcs(), storage, sizeof(storage)); sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobFont);
sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(storage, used, SkDeserialProcs()); char storage[2048];
canvas->drawTextBlob(copy, 20, 20, SkPaint()); size_t used = blob->serialize(SkSerialProcs(), storage, sizeof(storage));
std::string usage = "size=" + std::to_string(sizeof(storage)) + " used=" + std::to_string(used); sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(storage, used, SkDeserialProcs());
canvas->drawString(usage.c_str(), 20, 40, SkPaint()); canvas->drawTextBlob(copy, 20, 20, SkPaint());
## std::string usage = "size=" + std::to_string(sizeof(storage)) + " used=" + std::to_string(used);
canvas->drawString(usage.c_str(), 20, 40, SkPaint());
#SeeAlso Deserialize SkSerialProcs ##
#Method ## #SeeAlso Deserialize SkSerialProcs
# ------------------------------------------------------------------------------ #Method ##
#Method sk_sp<SkData> serialize(const SkSerialProcs& procs) const # ------------------------------------------------------------------------------
#In Utility
#Line # writes Text_Blob to Data ## #Method sk_sp<SkData> serialize(const SkSerialProcs& procs) const
#Populate #In Utility
#Line # writes Text_Blob to Data ##
#Example #Populate
#Height 24
###$ #Example
$Function #Height 24
#include "SkSerialProcs.h" ###$
$$ $Function
$$$# #include "SkSerialProcs.h"
SkFont blobFont; $$
blobFont.setSize(24); $$$#
sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobFont); SkFont blobFont;
sk_sp<SkData> data = blob->serialize(SkSerialProcs()); blobFont.setSize(24);
sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs()); sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World", 11, blobFont);
canvas->drawTextBlob(copy, 20, 20, SkPaint()); sk_sp<SkData> data = blob->serialize(SkSerialProcs());
## sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());
canvas->drawTextBlob(copy, 20, 20, SkPaint());
#SeeAlso Deserialize SkData SkSerialProcs ##
#Method ## #SeeAlso Deserialize SkData SkSerialProcs
# ------------------------------------------------------------------------------ #Method ##
#Method static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size, const SkDeserialProcs& procs) # ------------------------------------------------------------------------------
#In Constructors
#Line # constructs Text_Blob from memory ## #Method static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size, const SkDeserialProcs& procs)
#Populate #In Constructors
#Line # constructs Text_Blob from memory ##
#Example #Populate
#Height 24
#Description #Example
Text "Hacker" replaces "World!", but does not update its metrics. #Height 24
When drawn, "Hacker" uses the spacing computed for "World!". #Description
## Text "Hacker" replaces "World!", but does not update its metrics.
###$ When drawn, "Hacker" uses the spacing computed for "World!".
$Function ##
#include "SkSerialProcs.h" ###$
$$ $Function
$$$# #include "SkSerialProcs.h"
SkFont blobFont; $$
blobFont.setSize(24); $$$#
sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World!", 12, blobFont); SkFont blobFont;
sk_sp<SkData> data = blob->serialize(SkSerialProcs()); blobFont.setSize(24);
uint16_t glyphs[6]; sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText("Hello World!", 12, blobFont);
SkPaint blobPaint; sk_sp<SkData> data = blob->serialize(SkSerialProcs());
blobPaint.textToGlyphs("Hacker", 6, glyphs); uint16_t glyphs[6];
memcpy((char*)data->writable_data() + 0x54, glyphs, sizeof(glyphs)); SkPaint blobPaint;
sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs()); blobPaint.textToGlyphs("Hacker", 6, glyphs);
canvas->drawTextBlob(copy, 20, 20, SkPaint()); memcpy((char*)data->writable_data() + 0x54, glyphs, sizeof(glyphs));
## sk_sp<SkTextBlob> copy = SkTextBlob::Deserialize(data->data(), data->size(), SkDeserialProcs());
canvas->drawTextBlob(copy, 20, 20, SkPaint());
#SeeAlso serialize SkDeserialProcs ##
#Method ## #SeeAlso serialize SkDeserialProcs
#Class SkTextBlob ## #Method ##
#Topic Text_Blob ## #Class SkTextBlob ##
#Topic Text_Blob ##

View File

@ -1828,7 +1828,9 @@ Definition* IncludeParser::findMethod(const Definition& bmhDef) {
className = className.substr(subClassPos + 2); className = className.substr(subClassPos + 2);
} }
// match may be constructor; compare strings to see if this is so // match may be constructor; compare strings to see if this is so
SkASSERT(string::npos != methodName.find('(')); if (string::npos == methodName.find('(')) {
return nullptr;
}
auto stripper = [](string s) -> string { auto stripper = [](string s) -> string {
bool last = false; bool last = false;
string result; string result;

View File

@ -1668,7 +1668,10 @@ void MdOut::markTypeOut(Definition* def, const Definition** prior) {
SkASSERT(MarkType::kMethod == parent->fMarkType); SkASSERT(MarkType::kMethod == parent->fMarkType);
// retrieve parameters, return, description from include // retrieve parameters, return, description from include
Definition* iMethod = fIncludeParser.findMethod(*parent); Definition* iMethod = fIncludeParser.findMethod(*parent);
SkASSERT(iMethod); // deprecated or 'in progress' functions should not include populate if (!iMethod) { // deprecated or 'in progress' functions should not include populate
SkDebugf("#Populate found in deprecated or missing method %s\n", def->fName.c_str());
def->fParent->reportError<void>("Remove #Method");
}
bool wroteParam = false; bool wroteParam = false;
SkASSERT(fMethod == iMethod); SkASSERT(fMethod == iMethod);
for (auto& entry : iMethod->fTokens) { for (auto& entry : iMethod->fTokens) {