void TextRenderGdiplus::Draw(const WCHAR *s, size_t sLen, RectF& bb, bool isRtl) { PointF pos; bb.GetLocation(&pos); if (!isRtl) { gfx->DrawString(s, (INT)sLen, currFont->font, pos, nullptr, textColorBrush); } else { StringFormat rtl; rtl.SetFormatFlags(StringFormatFlagsDirectionRightToLeft); pos.X += bb.Width; gfx->DrawString(s, (INT)sLen, currFont->font, pos, &rtl, textColorBrush); } }
// TODO: draw link in the appropriate format (blue text, underlined, should show hand cursor when // mouse is over a link. There's a slight complication here: we only get explicit information about // strings, not about the whitespace and we should underline the whitespace as well. Also the text // should be underlined at a baseline void DrawHtmlPage(Graphics *g, Vec<DrawInstr> *drawInstructions, REAL offX, REAL offY, bool showBbox, Color *textColor, bool *abortCookie) { Color kindleTextColor(0x5F, 0x4B, 0x32); // this color matches Kindle app if (!textColor) textColor = &kindleTextColor; SolidBrush brText(*textColor); Pen debugPen(Color(255, 0, 0), 1); //Pen linePen(Color(0, 0, 0), 2.f); Pen linePen(Color(0x5F, 0x4B, 0x32), 2.f); Font *font = NULL; WCHAR buf[512]; PointF pos; DrawInstr *i; for (i = drawInstructions->IterStart(); i; i = drawInstructions->IterNext()) { RectF bbox = i->bbox; bbox.X += offX; bbox.Y += offY; if (InstrLine == i->type) { // hr is a line drawn in the middle of bounding box REAL y = floorf(bbox.Y + bbox.Height / 2.f + 0.5f); PointF p1(bbox.X, y); PointF p2(bbox.X + bbox.Width, y); if (showBbox) g->DrawRectangle(&debugPen, bbox); g->DrawLine(&linePen, p1, p2); } else if (InstrString == i->type) { size_t strLen = str::Utf8ToWcharBuf(i->str.s, i->str.len, buf, dimof(buf)); bbox.GetLocation(&pos); if (showBbox) g->DrawRectangle(&debugPen, bbox); g->DrawString(buf, strLen, font, pos, NULL, &brText); } else if (InstrSetFont == i->type) { font = i->font; } else if ((InstrElasticSpace == i->type) || (InstrFixedSpace == i->type) || (InstrAnchor == i->type)) { // ignore } else if (InstrImage == i->type) { // TODO: cache the bitmap somewhere (?) Bitmap *bmp = BitmapFromData(i->img.data, i->img.len); if (bmp) g->DrawImage(bmp, bbox, 0, 0, (REAL)bmp->GetWidth(), (REAL)bmp->GetHeight(), UnitPixel); delete bmp; } else if (InstrLinkStart == i->type) { // TODO: set text color to blue REAL y = floorf(bbox.Y + bbox.Height + 0.5f); PointF p1(bbox.X, y); PointF p2(bbox.X + bbox.Width, y); Pen linkPen(*textColor); g->DrawLine(&linkPen, p1, p2); } else if (InstrLinkEnd == i->type) { // TODO: set text color back again } else if (InstrRtlString == i->type) { size_t strLen = str::Utf8ToWcharBuf(i->str.s, i->str.len, buf, dimof(buf)); bbox.GetLocation(&pos); if (showBbox) g->DrawRectangle(&debugPen, bbox); StringFormat rtl; rtl.SetFormatFlags(StringFormatFlagsDirectionRightToLeft); pos.X += bbox.Width; g->DrawString(buf, strLen, font, pos, &rtl, &brText); } else { CrashIf(true); } if (abortCookie && *abortCookie) break; } }