void SkSVGParser::ConvertToArray(SkString& vals) { vals.appendUnichar(']'); char* valCh = (char*) vals.c_str(); valCh[0] = '['; int index = 1; while (valCh[index] != ']') { while (is_whitespace(valCh[index])) index++; bool foundComma = false; char next; do { next = valCh[index++]; if (next == ',') { foundComma = true; continue; } if (next == ']') { index--; goto undoLastComma; } if (next == ' ') break; foundComma = false; } while (is_whitespace(next) == false); if (foundComma == false) valCh[index - 1] = ','; } undoLastComma: while (is_whitespace(valCh[--index])) ; if (valCh[index] == ',') valCh[index] = ' '; }
bool onQuery(SkEvent* evt) override { if (SampleCode::TitleQ(*evt)) { SampleCode::TitleR(evt, "Lua"); return true; } SkUnichar uni; if (SampleCode::CharQ(*evt, &uni)) { lua_State* L = this->ensureLua(); lua_getglobal(L, gUnicharName); if (lua_isfunction(L, -1)) { SkString str; str.appendUnichar(uni); fLua->pushString(str.c_str()); if (lua_pcall(L, 1, 1, 0) != LUA_OK) { SkDebugf("lua err: %s\n", lua_tostring(L, -1)); } else { if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) { this->inval(NULL); return true; } } } } return this->INHERITED::onQuery(evt); }
static SkScalar drawCharacter(SkCanvas* canvas, uint32_t character, SkScalar x, SkScalar y, SkPaint& paint, SkFontMgr* fm, const char* fontName, const char* bcp47[], int bcp47Count, const SkFontStyle& fontStyle) { // find typeface containing the requested character and draw it SkString ch; ch.appendUnichar(character); SkTypeface* typeface = fm->matchFamilyStyleCharacter(fontName, fontStyle, bcp47, bcp47Count, character); SkSafeUnref(paint.setTypeface(typeface)); x = drawString(canvas, ch, x, y, paint) + 20; if (nullptr == typeface) { return x; } // repeat the process, but this time use the family name of the typeface // from the first pass. This emulates the behavior in Blink where it // it expects to get the same glyph when following this pattern. SkString familyName; typeface->getFamilyName(&familyName); SkTypeface* typefaceCopy = fm->legacyCreateTypeface(familyName.c_str(), typeface->fontStyle()); SkSafeUnref(paint.setTypeface(typefaceCopy)); return drawString(canvas, ch, x, y, paint) + 20; }
bool onQuery(SkEvent* evt) override { if (SampleCode::TitleQ(*evt)) { SampleCode::TitleR(evt, "QuadStroker"); return true; } SkUnichar uni; if (fTextButton.fEnabled && SampleCode::CharQ(*evt, &uni)) { switch (uni) { case ' ': fText = ""; break; case '-': fTextSize = SkTMax(1.0f, fTextSize - 1); break; case '+': case '=': fTextSize += 1; break; default: fText.appendUnichar(uni); } this->inval(NULL); return true; } return this->INHERITED::onQuery(evt); }
static void SkStringFromMacRoman(const uint8_t* macRoman, size_t length, SkString& utf8) { utf8.reset(); for (size_t i = 0; i < length; ++i) { utf8.appendUnichar(macRoman[i] < 0x80 ? macRoman[i] : UnicodeFromMacRoman[macRoman[i] - 0x80]); } }
void SkSVGRadialGradient::translate(SkSVGParser& parser, bool defState) { if (fMatrixID.size() == 0) parser.translateMatrix(f_gradientTransform, &fMatrixID); parser._startElement("radialGradient"); if (fMatrixID.size() > 0) parser._addAttribute("matrix", fMatrixID); INHERITED::translateGradientUnits(f_gradientUnits); SkString center; center.appendUnichar('['); center.append(f_cx); center.appendUnichar(','); center.append(f_cy); center.appendUnichar(']'); parser._addAttribute("center", center); parser._addAttribute("radius", f_r); INHERITED::translate(parser, defState); parser._endElement(); }
static void SkStringFromUTF16BE(const uint16_t* utf16be, size_t length, SkString& utf8) { SkASSERT(utf16be != NULL); utf8.reset(); size_t numberOf16BitValues = length / 2; const uint16_t* end = utf16be + numberOf16BitValues; while (utf16be < end) { utf8.appendUnichar(SkUTF16BE_NextUnichar(&utf16be)); } }
void SkSVGLinearGradient::translate(SkSVGParser& parser, bool defState) { if (fMatrixID.size() == 0) parser.translateMatrix(f_gradientTransform, &fMatrixID); parser._startElement("linearGradient"); if (fMatrixID.size() > 0) parser._addAttribute("matrix", fMatrixID); INHERITED::translateGradientUnits(f_gradientUnits); SkString points; points.appendUnichar('['); points.append(f_x1); points.appendUnichar(','); points.append(f_y1); points.appendUnichar(','); points.append(f_x2); points.appendUnichar(','); points.append(f_y2); points.appendUnichar(']'); parser._addAttribute("points", points.c_str()); INHERITED::translate(parser, defState); parser._endElement(); }
void SkAppendScalar(SkString* str, SkScalar value, SkScalarAsStringType asType) { switch (asType) { case kHex_SkScalarAsStringType: str->appendf("SkBits2Float(0x%08x)", SkFloat2Bits(value)); break; case kDec_SkScalarAsStringType: { SkString tmp; tmp.printf("%g", value); if (tmp.contains('.')) { tmp.appendUnichar('f'); } str->append(tmp); break; } } }
SkString* SkObjectParser::TextToString(const void* text, size_t byteLength, SkPaint::TextEncoding encoding) { SkString* decodedText = new SkString(); switch (encoding) { case SkPaint::kUTF8_TextEncoding: { decodedText->append("UTF-8: "); decodedText->append((const char*)text, byteLength); break; } case SkPaint::kUTF16_TextEncoding: { decodedText->append("UTF-16: "); size_t sizeNeeded = SkUTF16_ToUTF8((uint16_t*)text, SkToS32(byteLength / 2), nullptr); SkAutoSTMalloc<0x100, char> utf8(sizeNeeded); SkUTF16_ToUTF8((uint16_t*)text, SkToS32(byteLength / 2), utf8); decodedText->append(utf8, sizeNeeded); break; } case SkPaint::kUTF32_TextEncoding: { decodedText->append("UTF-32: "); const SkUnichar* begin = (const SkUnichar*)text; const SkUnichar* end = (const SkUnichar*)((const char*)text + byteLength); for (const SkUnichar* unichar = begin; unichar < end; ++unichar) { decodedText->appendUnichar(*unichar); } break; } case SkPaint::kGlyphID_TextEncoding: { decodedText->append("GlyphID: "); const uint16_t* begin = (const uint16_t*)text; const uint16_t* end = (const uint16_t*)((const char*)text + byteLength); for (const uint16_t* glyph = begin; glyph < end; ++glyph) { decodedText->append("0x"); decodedText->appendHex(*glyph); decodedText->append(" "); } break; } default: decodedText->append("Unknown text encoding."); break; } return decodedText; }
void SkSVGPaint::setSave(SkSVGParser& parser) { SkTDArray<SkString*> clips; SkSVGPaint* walking = parser.fHead; int index; SkMatrix sum; sum.reset(); while (walking != NULL) { for (index = kInitial + 1; index < kTerminal; index++) { SkString* lastAttr = (*walking)[index]; if (lastAttr->size() == 0) continue; if (index == kTransform) { const char* str = lastAttr->c_str(); SkASSERT(strncmp(str, "matrix(", 7) == 0); str += 6; const char* strEnd = strrchr(str, ')'); SkASSERT(strEnd != NULL); SkString mat(str, strEnd - str); SkSVGParser::ConvertToArray(mat); SkScalar values[6]; SkParse::FindScalars(mat.c_str() + 1, values, 6); SkMatrix matrix; matrix.reset(); matrix.setScaleX(values[0]); matrix.setSkewY(values[1]); matrix.setSkewX(values[2]); matrix.setScaleY(values[3]); matrix.setTranslateX(values[4]); matrix.setTranslateY(values[5]); sum.setConcat(matrix, sum); continue; } if ( index == kClipPath) *clips.insert(0) = lastAttr; } walking = walking->fNext; } if ((sum == parser.fLastTransform) == false) { SkMatrix inverse; bool success = parser.fLastTransform.invert(&inverse); SkASSERT(success == true); SkMatrix output; output.setConcat(inverse, sum); parser.fLastTransform = sum; SkString outputStr; outputStr.appendUnichar('['); outputStr.appendScalar(output.getScaleX()); outputStr.appendUnichar(','); outputStr.appendScalar(output.getSkewX()); outputStr.appendUnichar(','); outputStr.appendScalar(output.getTranslateX()); outputStr.appendUnichar(','); outputStr.appendScalar(output.getSkewY()); outputStr.appendUnichar(','); outputStr.appendScalar(output.getScaleY()); outputStr.appendUnichar(','); outputStr.appendScalar(output.getTranslateY()); outputStr.appendUnichar(','); outputStr.appendScalar(output.getPerspX()); outputStr.appendUnichar(','); outputStr.appendScalar(output.getPerspY()); outputStr.append(",1]"); parser._startElement("matrix"); parser._addAttributeLen("matrix", outputStr.c_str(), outputStr.size()); parser._endElement(); } #if 0 // incomplete if (parser.fTransformClips.size() > 0) { // need to reset the clip when the 'g' scope is ended parser._startElement("add"); const char* start = strchr(current->f_clipPath.c_str(), '#') + 1; SkASSERT(start); parser._addAttributeLen("use", start, strlen(start) - 1); parser._endElement(); // clip } #endif }