void DrawBorder(Graphics *gfx, const Rect r, CachedStyle *s) { Point p1, p2; float width; // top p1.X = r.X; p1.Y = r.Y; p2.X = r.X + r.Width; p2.Y = p1.Y; width = s->borderWidth.top; Brush *br = BrushFromColorData(s->borderColors.top, r); DrawLine(gfx, p1, p2, width, br); // right p1 = p2; p2.X = p1.X; p2.Y = p1.Y + r.Height; width = s->borderWidth.right; br = BrushFromColorData(s->borderColors.right, r); DrawLine(gfx, p1, p2, width, br); // bottom p1 = p2; p2.X = r.X; p2.Y = p1.Y; width = s->borderWidth.bottom; br = BrushFromColorData(s->borderColors.bottom, r); DrawLine(gfx, p1, p2, width, br); // left p1 = p2; p2.X = p1.X; p2.Y = r.Y; width = s->borderWidth.left; br = BrushFromColorData(s->borderColors.left, r); DrawLine(gfx, p1, p2, width, br); }
void ButtonVector::Paint(Graphics *gfx, int offX, int offY) { if (!IsVisible()) return; CachedStyle *s = cachedStyle; RectF bbox((REAL)offX, (REAL)offY, (REAL)pos.Width, (REAL)pos.Height); Brush *brBgColor = BrushFromColorData(s->bgColor, bbox); gfx->FillRectangle(brBgColor, bbox); Rect r(offX, offY, pos.Width, pos.Height); DrawBorder(gfx, r, s); if (!graphicsPath) return; // graphicsPath bbox can have non-zero X,Y Rect gpBbox; Brush *brFill = BrushFromColorData(s->fill, bbox); Brush *brStroke = BrushFromColorData(s->stroke, bbox); Pen pen(brStroke, s->strokeWidth); pen.SetMiterLimit(1.f); pen.SetAlignment(PenAlignmentInset); if (0.f == s->strokeWidth) graphicsPath->GetBounds(&gpBbox); else graphicsPath->GetBounds(&gpBbox, NULL, &pen); // calculate the position of graphics path within given button position, size // and desired vertical/horizontal alignment. // Note: alignment is calculated against the size after substracting // ncSize is the size of the non-client parts i.e. border and padding, on both sides Size ncSize = GetBorderAndPaddingSize(s); int elOffY = s->vertAlign.CalcOffset( gpBbox.Height, pos.Height - ncSize.Height); int elOffX = s->horizAlign.CalcOffset(gpBbox.Width, pos.Width - ncSize.Width ); int x = offX + elOffX + s->padding.left + (int)s->borderWidth.left + gpBbox.X; int y = offY + elOffY + s->padding.top + (int)s->borderWidth.top + gpBbox.Y; // TODO: can I avoid making a copy of GraphicsPath? GraphicsPath *tmp = graphicsPath->Clone(); Matrix m; m.Translate((float)x, (float)y); tmp->Transform(&m); gfx->FillPath(brFill, tmp); if (0.f != s->strokeWidth) gfx->DrawPath(&pen, tmp); }
// TODO: the position still seems a bit off wrt. padding void ButtonVector::RecalculateSize(bool repaintIfSizeDidntChange) { Size prevSize = desiredSize; CachedStyle *s = cachedStyle; desiredSize = GetBorderAndPaddingSize(s); Rect bbox; Brush *brStroke = BrushFromColorData(s->stroke, bbox); if (0.f == s->strokeWidth) { graphicsPath->GetBounds(&bbox); } else { Pen pen(brStroke, s->strokeWidth); // pen widith is multiplied by MiterLimit(), which is 10 by default // so set it explicitly to 1 for the size we expect pen.SetMiterLimit(1.f); pen.SetAlignment(PenAlignmentInset); graphicsPath->GetBounds(&bbox, NULL, &pen); } desiredSize.Width += bbox.Width; desiredSize.Height += bbox.Height; if (!prevSize.Equals(desiredSize)) RequestLayout(this); else if (repaintIfSizeDidntChange) RequestRepaint(this); }
// we paint the background in Painter() because I don't // want to add an artificial Control window just to cover // the whole HWND and paint the background. void Painter::PaintBackground(Graphics *g, Rect r) { // TODO: don't quite get why I need to expand the rectangle, but // sometimes there's a seemingly 1 pixel artifact on the left and // at the top if I don't do this r.Inflate(1,1); ColorData *bgColor = wnd->cachedStyle->bgColor; Brush *br = BrushFromColorData(bgColor, r); g->FillRectangle(br, r); }
void ScrollBar::Paint(Graphics *gfx, int offX, int offY) { CrashIf(!IsVisible()); // TODO: take padding into account CachedStyle *s = cachedStyle; int dy = inactiveDy; if (IsMouseOver()) dy = onOverDy; Rect r(offX, offY + pos.Height - dy, pos.Width, dy); Brush *br = BrushFromColorData(s->bgColor, r); gfx->FillRectangle(br, r); int filledDx = IntFromPerc(pos.Width, filledPerc); if (0 == filledDx) return; r.Width = filledDx; br = BrushFromColorData(s->color, r); gfx->FillRectangle(br, r); }
void PageControl::Paint(Graphics *gfx, int offX, int offY) { CrashIf(!IsVisible()); Timer timerAll; CachedStyle *s = cachedStyle; Timer timerFill; Rect r(offX, offY, pos.Width, pos.Height); if (!s->bgColor->IsTransparent()) { Brush *br = BrushFromColorData(s->bgColor, r); gfx->FillRectangle(br, r); } double durFill = timerFill.Stop(); if (!page) return; // during resize the page we currently show might be bigger than // our area. To avoid drawing outside our area we clip Region origClipRegion; gfx->GetClip(&origClipRegion); r.X += s->padding.left; r.Y += s->padding.top; r.Width -= (s->padding.left + s->padding.right); r.Height -= (s->padding.top + s->padding.bottom); r.Inflate(1,0); gfx->SetClip(r, CombineModeReplace); Color textColor; if (gGlobalPrefs->useSysColors) textColor.SetFromCOLORREF(GetSysColor(COLOR_WINDOWTEXT)); else textColor.SetFromCOLORREF(gGlobalPrefs->ebookUI.textColor); ITextRender *textRender = CreateTextRender(GetTextRenderMethod(), gfx); Color bgCol; if (gGlobalPrefs->useSysColors) bgCol.SetFromCOLORREF(GetSysColor(COLOR_WINDOW)); else bgCol.SetFromCOLORREF(gGlobalPrefs->ebookUI.backgroundColor); textRender->SetTextBgColor(bgCol); Timer timerDrawHtml; DrawHtmlPage(gfx, textRender, &page->instructions, (REAL)r.X, (REAL)r.Y, IsDebugPaint(), textColor); double durDraw = timerDrawHtml.Stop(); gfx->SetClip(&origClipRegion, CombineModeReplace); delete textRender; double durAll = timerAll.Stop(); plogf("all: %.2f, fill: %.2f, draw html: %.2f", durAll, durFill, durDraw); }
void Button::Paint(Graphics *gfx, int offX, int offY) { CrashIf(!IsVisible()); CachedStyle *s = cachedStyle; RectF bbox((REAL)offX, (REAL)offY, (REAL)pos.Width, (REAL)pos.Height); Brush *brBgColor = BrushFromColorData(s->bgColor, bbox); gfx->FillRectangle(brBgColor, bbox); Rect r(offX, offY, pos.Width, pos.Height); DrawBorder(gfx, r, s); if (str::IsEmpty(text)) return; Padding pad = s->padding; int alignedOffX = AlignedOffset(pos.Width - pad.left - pad.right, textDx, s->textAlign); int x = offX + alignedOffX + pad.left + (int)s->borderWidth.left; int y = offY + pad.top + (int)s->borderWidth.top; Brush *brColor = BrushFromColorData(s->color, bbox); // restrict bbox to just the text? Font *font = GetCachedFont(s->fontName, s->fontSize, s->fontWeight); gfx->DrawString(text, str::Len(text), font, PointF((REAL)x, (REAL)y), NULL, brColor); }
void Grid::Paint(Graphics* gfx, int offX, int offY) { CrashIf(!IsVisible()); CachedStyle* s = cachedStyle; RectF bbox((REAL)offX, (REAL)offY, (REAL)pos.Width, (REAL)pos.Height); Brush* brBgColor = BrushFromColorData(s->bgColor, bbox); gfx->FillRectangle(brBgColor, bbox); Rect r(offX, offY, pos.Width, pos.Height); DrawBorder(gfx, r, s); for (Grid::CellData& d : els) { if (!d.cachedStyle) continue; Rect cellRect(GetCellBbox(&d)); cellRect.X += offX; cellRect.Y += offY; s = d.cachedStyle; DrawBorder(gfx, cellRect, s); } }
void PageControl::Paint(Graphics *gfx, int offX, int offY) { CrashIf(!IsVisible()); #if 0 // for testing mouse move, paint a blue circle at current cursor position if ((-1 != cursorX) && (-1 != cursorY)) { SolidBrush br(Color(180, 0, 0, 255)); int x = offX + cursorX; int y = offY + cursorY; Rect r(RectForCircle(x, y, 10)); gfx->FillEllipse(&br, r); } #endif CachedStyle *s = cachedStyle; Rect r(offX, offY, pos.Width, pos.Height); Brush *br = BrushFromColorData(s->bgColor, r); gfx->FillRectangle(br, r); if (!page) return; // during resize the page we currently show might be bigger than // our area. To avoid drawing outside our area we clip Region origClipRegion; gfx->GetClip(&origClipRegion); r.X += s->padding.left; r.Y += s->padding.top; r.Width -= (s->padding.left + s->padding.right); r.Height -= (s->padding.top + s->padding.bottom); r.Inflate(1,0); gfx->SetClip(r, CombineModeReplace); // TODO: support changing the text color to gRenderCache.colorRange[0] // or GetSysColor(COLOR_WINDOWTEXT) if gGlobalPrefs.useSysColors DrawHtmlPage(gfx, &page->instructions, (REAL)r.X, (REAL)r.Y, IsDebugPaint()); gfx->SetClip(&origClipRegion, CombineModeReplace); }
Brush *BrushFromColorData(ColorData *color, const Rect& r) { return BrushFromColorData(color, RectF((float)r.X, (float)r.Y, (float)r.Width, (float)r.Height)); }