status_t ServerFont::GetGlyphShapes(const char charArray[], int32 numChars, BShape* shapeArray[]) const { if (!charArray || numChars <= 0 || !shapeArray) return B_BAD_DATA; FT_Face face = GetTransformedFace(true, true); if (!face) return B_ERROR; FT_Outline_Funcs funcs; funcs.move_to = MoveToFunc; funcs.line_to = LineToFunc; funcs.conic_to = ConicToFunc; funcs.cubic_to = CubicToFunc; funcs.shift = 0; funcs.delta = 0; const char* string = charArray; for (int i = 0; i < numChars; i++) { shapeArray[i] = new (std::nothrow) BShape(); if (shapeArray[i] == NULL) { PutTransformedFace(face); return B_NO_MEMORY; } FT_Load_Char(face, UTF8ToCharCode(&string), FT_LOAD_NO_BITMAP); FT_Outline outline = face->glyph->outline; FT_Outline_Decompose(&outline, &funcs, shapeArray[i]); shapeArray[i]->Close(); } PutTransformedFace(face); return B_OK; }
bool ParagraphLayout::_AppendGlyphInfos(const TextSpan& span) { int charCount = span.CountChars(); if (charCount == 0) return true; const BString& text = span.Text(); const BFont& font = span.Style().Font(); // Allocate arrays float* escapementArray = new (std::nothrow) float[charCount]; if (escapementArray == NULL) return false; ArrayDeleter<float> escapementDeleter(escapementArray); // Fetch glyph spacing information font.GetEscapements(text, charCount, escapementArray); // Append to glyph buffer and convert escapement scale float size = font.Size(); const char* c = text.String(); for (int i = 0; i < charCount; i++) { if (!_AppendGlyphInfo(UTF8ToCharCode(&c), escapementArray[i] * size, span.Style())) { return false; } } return true; }
bool FontCacheEntry::HasGlyphs(const char* utf8String, ssize_t length) const { uint32 glyphCode; const char* start = utf8String; while ((glyphCode = UTF8ToCharCode(&utf8String))) { if (fGlyphCache->FindGlyph(glyphCode) == NULL) return false; if (utf8String - start + 1 > length) break; } return true; }
bool FontCacheEntry::HasGlyphs(const char* utf8String, ssize_t length) const { uint32 charCode; const char* start = utf8String; while ((charCode = UTF8ToCharCode(&utf8String))) { uint32 glyphIndex = fEngine.GlyphIndexForGlyphCode(charCode); if (!fGlyphCache->FindGlyph(glyphIndex)) return false; if (utf8String - start + 1 > length) break; } return true; }
void MarkupParser::_ParseText(const BString& text) { int32 start = 0; int32 offset = 0; int32 charCount = text.CountChars(); const char* c = text.String(); while (offset <= charCount) { uint32 nextChar = UTF8ToCharCode(&c); switch (nextChar) { case '\n': case '\0': _CopySpan(text, start, offset); _FinishParagraph(); start = offset + 1; break; case '\'': if (offset + 2 < charCount && c[0] == '\'') { int32 tickCount = 2; if (c[1] == '\'') tickCount = 3; // Copy previous span using current style, excluding the // ticks. _CopySpan(text, start, offset); if (tickCount == 2) _ToggleStyle(fItalicStyle); else if (tickCount == 3) _ToggleStyle(fBoldStyle); // Don't include the ticks in the next span. offset += tickCount - 1; start = offset + 1; c += tickCount - 1; } break; case '=': // Detect headings if (offset == start && fCurrentParagraph.IsEmpty() && offset + 2 < charCount && c[0] == '=' && c[1] == ' ') { fCurrentParagraph.SetStyle(fHeadingParagraphStyle); fCurrentCharacterStyle = &fHeadingStyle; offset += 2; c += 2; start = offset + 1; } else if (offset > start && offset + 2 < charCount && c[0] == '=' && c[1] == '\n') { _CopySpan(text, start, offset - 1); _FinishParagraph(); offset += 2; c += 2; start = offset + 1; } break; case ' ': // Detect bullets at line starts if (offset == start && fCurrentParagraph.IsEmpty() && offset + 2 < charCount && c[0] == '*' && c[1] == ' ') { fCurrentParagraph.SetStyle(fBulletStyle); offset += 2; c += 2; start = offset + 1; } break; default: break; } offset++; } }
void MarkupParser::_ParseText(const BString& text) { int32 start = 0; int32 offset = 0; int32 charCount = text.CountChars(); const char* c = text.String(); while (offset <= charCount) { uint32 nextChar = UTF8ToCharCode(&c); switch (nextChar) { // Requires two line-breaks to start a new paragraph, unles the current // paragraph is already considered a bullet list item. Doesn't work well // with current set of packages. // case '\n': // _CopySpan(text, start, offset); // if (offset + 1 < charCount && c[0] == '\n') { // _FinishParagraph(); // offset += 1; // c += 1; // } else if (fCurrentParagraph.Style() == fBulletStyle) { // _FinishParagraph(); // } // start = offset + 1; // break; case '\n': _CopySpan(text, start, offset); if (offset > 0 && c[-1] != ' ') _FinishParagraph(offset >= charCount); start = offset + 1; break; case '\0': _CopySpan(text, start, offset); _FinishParagraph(true); start = offset + 1; break; case '\'': if (offset + 2 < charCount && c[0] == '\'') { int32 tickCount = 2; if (c[1] == '\'') tickCount = 3; // Copy previous span using current style, excluding the // ticks. _CopySpan(text, start, offset); if (tickCount == 2) _ToggleStyle(fItalicStyle); else if (tickCount == 3) _ToggleStyle(fBoldStyle); // Don't include the ticks in the next span. offset += tickCount - 1; start = offset + 1; c += tickCount - 1; } break; case '=': // Detect headings if (offset == start && fCurrentParagraph.IsEmpty() && offset + 2 < charCount && c[0] == '=' && c[1] == ' ') { fCurrentParagraph.SetStyle(fHeadingParagraphStyle); fCurrentCharacterStyle = &fHeadingStyle; offset += 2; c += 2; start = offset + 1; } else if (offset > start && offset + 2 < charCount && c[0] == '=' && c[1] == '\n') { _CopySpan(text, start, offset - 1); offset += 2; c += 2; _FinishParagraph(offset >= charCount); start = offset + 1; } break; case ' ': // Detect bullets at line starts (preceeding space) if (offset == start && fCurrentParagraph.IsEmpty() && offset + 2 < charCount && (c[0] == '*' || c[0] == '-') && c[1] == ' ') { fCurrentParagraph.SetStyle(fBulletStyle); offset += 2; c += 2; start = offset + 1; } break; case '*': case '-': // Detect bullets at line starts (no preceeding space) if (offset == start && fCurrentParagraph.IsEmpty() && offset + 1 < charCount && c[0] == ' ') { fCurrentParagraph.SetStyle(fBulletStyle); offset += 1; c += 1; start = offset + 1; } break; default: break; } offset++; } }