void drawWrappedText(RenderingContext* rc, SkCanvas* cv, TextDrawInfo* text, float textSize, SkPaint& paintText) { if(text->textWrap == 0) { // set maximum for all text text->textWrap = 40; } if(text->text.length() > text->textWrap) { int start = 0; int end = text->text.length(); int lastSpace = -1; int line = 0; int pos = 0; int limit = 0; while(pos < end) { lastSpace = -1; limit += text->textWrap; // in UTF-8 all non ASCII characters has 2 or more characters int symbolsRead = 0; int utf8pos = pos; while(symbolsRead < limit && pos < end) { if(utf8pos == pos) { if(text->text.at(pos) <= 128) { symbolsRead++; if(!isLetterOrDigit(text->text.at(pos))) { lastSpace = pos; } utf8pos ++; } } else { // here could be code to determine if UTF-8 is ended (currently only 2 chars) symbolsRead++; utf8pos = pos + 1; } pos++; } if(lastSpace == -1) { PROFILE_NATIVE_OPERATION(rc, drawTextOnCanvas(cv, text->text.substr(start, pos), text->centerX, text->centerY + line * (textSize + 2), paintText, text->textShadow)); start = pos; } else { PROFILE_NATIVE_OPERATION(rc, drawTextOnCanvas(cv, text->text.substr(start, lastSpace), text->centerX, text->centerY + line * (textSize + 2), paintText, text->textShadow)); start = lastSpace + 1; limit += (start - pos) - 1; } line++; } } else { PROFILE_NATIVE_OPERATION(rc, drawTextOnCanvas(cv, text->text, text->centerX, text->centerY, paintText, text->textShadow)); } }
void drawWrappedText(RenderingContext* rc, SkCanvas* cv, TextDrawInfo* text, float textSize, SkPaint& paintText) { if(text->textWrap == 0) { // set maximum for all text text->textWrap = 40; } if(text->text.length() > text->textWrap) { const char* c_str = text->text.c_str(); int end = text->text.length(); int line = 0; int pos = 0; int start = 0; while(start < end) { const char* p_str = c_str; int lastSpace = -1; int prevPos = -1; int charRead = 0; do { int lastSpace = nextWord((uint8_t*)p_str, &charRead); if (lastSpace == -1) { pos = end; } else { p_str += lastSpace; if(pos != start && charRead >= text->textWrap){ break; } pos += lastSpace; } } while(pos < end && charRead < text->textWrap); PROFILE_NATIVE_OPERATION(rc, drawTextOnCanvas(cv, c_str, pos - start , text->centerX, text->centerY + line * (textSize + 2), paintText, text->textShadow)); c_str += (pos - start); start = pos; line++; } } else { PROFILE_NATIVE_OPERATION(rc, drawTextOnCanvas(cv, text->text.data(), text->text.length(), text->centerX, text->centerY, paintText, text->textShadow)); } }
void drawTextOverCanvas(RenderingContext* rc, SkCanvas* cv) { SkRect r = SkRect::MakeLTRB(0, 0, rc->getWidth(), rc->getHeight()); r.inset(-100, -100); quad_tree<TextDrawInfo*> boundsIntersect(r, 4, 0.6); SkPaint paintIcon; paintIcon.setStyle(SkPaint::kStroke_Style); paintIcon.setStrokeWidth(1); paintIcon.setColor(0xff000000); paintIcon.setFilterBitmap(true); SkPaint paintText; paintText.setStyle(SkPaint::kFill_Style); paintText.setStrokeWidth(1); paintText.setColor(0xff000000); paintText.setTextAlign(SkPaint::kCenter_Align); if(!sTypeface) sTypeface = SkTypeface::CreateFromName("Droid Serif", SkTypeface::kNormal); paintText.setTypeface(sTypeface); paintText.setAntiAlias(true); SkPaint::FontMetrics fm; // 1. Sort text using text order std::sort(rc->textToDraw.begin(), rc->textToDraw.end(), textOrder); for (uint32_t i = 0; i < rc->textToDraw.size(); i++) { TextDrawInfo* text = rc->textToDraw.at(i); if (text->text.length() > 0) { // sest text size before finding intersection (it is used there) float textSize = rc->getDensityValue(text->textSize); paintText.setTextSize(textSize); paintText.setFakeBoldText(text->bold); paintText.setColor(text->textColor); // align center y paintText.getFontMetrics(&fm); text->centerY += (-fm.fAscent); // calculate if there is intersection bool intersects = findTextIntersection(cv, rc, boundsIntersect, text, &paintText, &paintIcon); if (!intersects) { if(rc->interrupted()){ return; } if (text->drawOnPath && text->path != NULL) { if (text->textShadow > 0) { paintText.setColor(0xFFFFFFFF); paintText.setStyle(SkPaint::kStroke_Style); paintText.setStrokeWidth(2 + text->textShadow); rc->nativeOperations.Pause(); cv->drawTextOnPathHV(text->text.c_str(), text->text.length(), *text->path, text->hOffset, text->vOffset, paintText); rc->nativeOperations.Start(); // reset paintText.setStyle(SkPaint::kFill_Style); paintText.setStrokeWidth(2); paintText.setColor(text->textColor); } rc->nativeOperations.Pause(); cv->drawTextOnPathHV(text->text.c_str(), text->text.length(), *text->path, text->hOffset, text->vOffset, paintText); rc->nativeOperations.Start(); } else { if (text->shieldRes.length() > 0) { SkBitmap* ico = getCachedBitmap(rc, text->shieldRes); if (ico != NULL) { float left = text->centerX - rc->getDensityValue(ico->width() / 2) - 0.5f; float top = text->centerY - rc->getDensityValue(ico->height() / 2) - rc->getDensityValue(4.5f); SkRect r = SkRect::MakeXYWH(left, top, rc->getDensityValue(ico->width()), rc->getDensityValue(ico->height())); PROFILE_NATIVE_OPERATION(rc, cv->drawBitmapRect(*ico, (SkIRect*) NULL, r, &paintIcon)); } } drawWrappedText(rc, cv, text, textSize, paintText); } } } } }