From cc77a652b217ab02456cea0b13e576d335407876 Mon Sep 17 00:00:00 2001 From: "pavlov%pavlov.net" Date: Mon, 17 Jul 2006 23:45:21 +0000 Subject: [PATCH] cleanup of some of the thebes code. bug 344979. r=vlad speed up measuring of spaces. bug 342366. r=vlad --- gfx/src/thebes/nsThebesFontMetrics.cpp | 20 +- gfx/src/thebes/nsThebesRenderingContext.cpp | 4 +- gfx/thebes/public/gfxContext.h | 14 +- gfx/thebes/public/gfxPoint.h | 2 +- gfx/thebes/src/gfxContext.cpp | 232 +++++++++++++------- 5 files changed, 182 insertions(+), 90 deletions(-) diff --git a/gfx/src/thebes/nsThebesFontMetrics.cpp b/gfx/src/thebes/nsThebesFontMetrics.cpp index 965abbbc508..530c633a1a6 100644 --- a/gfx/src/thebes/nsThebesFontMetrics.cpp +++ b/gfx/src/thebes/nsThebesFontMetrics.cpp @@ -113,7 +113,7 @@ nsThebesFontMetrics::Destroy() return NS_OK; } -#define ROUND_TO_TWIPS(x) NSToCoordRound((x) * mDev2App) +#define ROUND_TO_TWIPS(x) (nscoord)floor(((x) * mDev2App) + 0.5) const gfxFont::Metrics& nsThebesFontMetrics::GetMetrics() const { @@ -267,7 +267,7 @@ nsThebesFontMetrics::GetLeading(nscoord& aLeading) NS_IMETHODIMP nsThebesFontMetrics::GetNormalLineHeight(nscoord& aLineHeight) { - const gfxFont::Metrics &m = GetMetrics(); + const gfxFont::Metrics& m = GetMetrics(); aLineHeight = ROUND_TO_TWIPS(m.emHeight + m.internalLeading); return NS_OK; } @@ -275,7 +275,9 @@ nsThebesFontMetrics::GetNormalLineHeight(nscoord& aLineHeight) PRInt32 nsThebesFontMetrics::GetMaxStringLength() { - PRInt32 len = (PRInt32)floor(32767.0/GetMetrics().maxAdvance); + const gfxFont::Metrics& m = GetMetrics(); + const double x = 32767.0 / m.maxAdvance; + PRInt32 len = (PRInt32)floor(x); return PR_MAX(1, len); } @@ -288,6 +290,10 @@ nsThebesFontMetrics::GetWidth(const char* aString, PRUint32 aLength, nscoord& aW return NS_OK; } + // callers that hit this should not be so stupid + if ((aLength == 1) && (aString[0] == ' ')) + return GetSpaceWidth(aWidth); + const nsDependentCSubstring& theString = nsDependentCSubstring(aString, aString+aLength); nsRefPtr textrun = mFontGroup->MakeTextRun(theString); @@ -308,6 +314,10 @@ nsThebesFontMetrics::GetWidth(const PRUnichar* aString, PRUint32 aLength, return NS_OK; } + // callers that hit this should not be so stupid + if ((aLength == 1) && (aString[0] == ' ')) + return GetSpaceWidth(aWidth); + const nsDependentSubstring& theString = nsDependentSubstring(aString, aString+aLength); nsRefPtr textrun = mFontGroup->MakeTextRun(theString); @@ -385,7 +395,7 @@ nsThebesFontMetrics::DrawString(const char *aString, PRUint32 aLength, textrun->SetSpacing(spacing); } - textrun->Draw(aContext->Thebes(), gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev))); + aContext->Thebes()->DrawTextRun(textrun, gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev))); return NS_OK; } @@ -420,7 +430,7 @@ nsThebesFontMetrics::DrawString(const PRUnichar* aString, PRUint32 aLength, textrun->SetSpacing(spacing); } - textrun->Draw(aContext->Thebes(), gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev))); + aContext->Thebes()->DrawTextRun(textrun, gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev))); return NS_OK; } diff --git a/gfx/src/thebes/nsThebesRenderingContext.cpp b/gfx/src/thebes/nsThebesRenderingContext.cpp index 718d9541307..4375b30c36f 100644 --- a/gfx/src/thebes/nsThebesRenderingContext.cpp +++ b/gfx/src/thebes/nsThebesRenderingContext.cpp @@ -552,8 +552,8 @@ nsThebesRenderingContext::DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoor p0 = mThebes->UserToDevice(p0); p1 = mThebes->UserToDevice(p1); - p0.round(); - p1.round(); + p0.Round(); + p1.Round(); mThebes->IdentityMatrix(); diff --git a/gfx/thebes/public/gfxContext.h b/gfx/thebes/public/gfxContext.h index fedd75339b4..849b84e7ba8 100644 --- a/gfx/thebes/public/gfxContext.h +++ b/gfx/thebes/public/gfxContext.h @@ -205,7 +205,7 @@ public: * Draw the text run at the current point. * XXX support drawing subsections of the text run */ - void DrawText(gfxTextRun& text); + void DrawTextRun(gfxTextRun *text, gfxPoint pt); /** ** Transformation Matrix manipulation @@ -257,39 +257,39 @@ public: * Converts a point from device to user coordinates using the inverse * transformation matrix. */ - gfxPoint DeviceToUser(gfxPoint point) const; + gfxPoint DeviceToUser(const gfxPoint& point) const; /** * Converts a size from device to user coordinates. This does not apply * translation components of the matrix. */ - gfxSize DeviceToUser(gfxSize size) const; + gfxSize DeviceToUser(const gfxSize& size) const; /** * Converts a rectangle from device to user coordinates; this has the * same effect as using DeviceToUser on both the rectangle's point and * size. */ - gfxRect DeviceToUser(gfxRect rect) const; + gfxRect DeviceToUser(const gfxRect& rect) const; /** * Converts a point from user to device coordinates using the inverse * transformation matrix. */ - gfxPoint UserToDevice(gfxPoint point) const; + gfxPoint UserToDevice(const gfxPoint& point) const; /** * Converts a size from user to device coordinates. This does not apply * translation components of the matrix. */ - gfxSize UserToDevice(gfxSize size) const; + gfxSize UserToDevice(const gfxSize& size) const; /** * Converts a rectangle from user to device coordinates; this has the * same effect as using DeviceToUser on both the rectangle's point and * size. */ - gfxRect UserToDevice(gfxRect rect) const; + gfxRect UserToDevice(const gfxRect& rect) const; /** * Takes the given rect and tries to align it to device pixels. If diff --git a/gfx/thebes/public/gfxPoint.h b/gfx/thebes/public/gfxPoint.h index b66efad3319..12af992c1e5 100644 --- a/gfx/thebes/public/gfxPoint.h +++ b/gfx/thebes/public/gfxPoint.h @@ -107,7 +107,7 @@ struct THEBES_API gfxPoint { gfxPoint operator/(const gfxFloat v) const { return gfxPoint(x / v, y / v); } - gfxPoint& round() { + gfxPoint& Round() { x = ::floor(x + 0.5); y = ::floor(y + 0.5); return *this; diff --git a/gfx/thebes/src/gfxContext.cpp b/gfx/thebes/src/gfxContext.cpp index 097c1c0a506..559c055ff13 100644 --- a/gfx/thebes/src/gfxContext.cpp +++ b/gfx/thebes/src/gfxContext.cpp @@ -62,90 +62,108 @@ gfxContext::~gfxContext() cairo_destroy(mCairo); } -gfxASurface *gfxContext::OriginalSurface() +gfxASurface * +gfxContext::OriginalSurface() { return mSurface; } -already_AddRefed gfxContext::CurrentSurface(gfxFloat *dx, gfxFloat *dy) +already_AddRefed +gfxContext::CurrentSurface(gfxFloat *dx, gfxFloat *dy) { cairo_surface_t *s = cairo_get_group_target(mCairo); if (s == mSurface->CairoSurface()) { if (dx && dy) - cairo_surface_get_device_offset (s, dx, dy); + cairo_surface_get_device_offset(s, dx, dy); gfxASurface *ret = mSurface; NS_ADDREF(ret); return ret; } if (dx && dy) - cairo_surface_get_device_offset (s, dx, dy); + cairo_surface_get_device_offset(s, dx, dy); return gfxASurface::Wrap(s); } -void gfxContext::Save() +void +gfxContext::Save() { cairo_save(mCairo); } -void gfxContext::Restore() +void +gfxContext::Restore() { cairo_restore(mCairo); } // drawing -void gfxContext::NewPath() +void +gfxContext::NewPath() { cairo_new_path(mCairo); } -void gfxContext::ClosePath() + +void +gfxContext::ClosePath() { cairo_close_path(mCairo); } -gfxPoint gfxContext::CurrentPoint() const +gfxPoint +gfxContext::CurrentPoint() const { double x, y; cairo_get_current_point(mCairo, &x, &y); return gfxPoint(x, y); } -void gfxContext::Stroke() +void +gfxContext::Stroke() { cairo_stroke_preserve(mCairo); } -void gfxContext::Fill() + +void +gfxContext::Fill() { cairo_fill_preserve(mCairo); } -void gfxContext::MoveTo(gfxPoint pt) +void +gfxContext::MoveTo(gfxPoint pt) { cairo_move_to(mCairo, pt.x, pt.y); } -void gfxContext::LineTo(gfxPoint pt) + +void +gfxContext::LineTo(gfxPoint pt) { cairo_line_to(mCairo, pt.x, pt.y); } -void gfxContext::CurveTo(gfxPoint pt1, gfxPoint pt2, gfxPoint pt3) +void +gfxContext::CurveTo(gfxPoint pt1, gfxPoint pt2, gfxPoint pt3) { cairo_curve_to(mCairo, pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y); } -void gfxContext::Arc(gfxPoint center, gfxFloat radius, +void +gfxContext::Arc(gfxPoint center, gfxFloat radius, gfxFloat angle1, gfxFloat angle2) { cairo_arc(mCairo, center.x, center.y, radius, angle1, angle2); } -void gfxContext::NegativeArc(gfxPoint center, gfxFloat radius, +void +gfxContext::NegativeArc(gfxPoint center, gfxFloat radius, gfxFloat angle1, gfxFloat angle2) { cairo_arc_negative(mCairo, center.x, center.y, radius, angle1, angle2); } -void gfxContext::Line(gfxPoint start, gfxPoint end) +void +gfxContext::Line(gfxPoint start, gfxPoint end) { MoveTo(start); LineTo(end); @@ -155,7 +173,8 @@ void gfxContext::Line(gfxPoint start, gfxPoint end) // rectangles and for even-width stroked rectangles. // For odd-width stroked rectangles, we need to offset x/y by // 0.5... -void gfxContext::Rectangle(gfxRect rect, PRBool snapToPixels) +void +gfxContext::Rectangle(gfxRect rect, PRBool snapToPixels) { if (snapToPixels) { gfxRect snappedRect(rect); @@ -174,7 +193,8 @@ void gfxContext::Rectangle(gfxRect rect, PRBool snapToPixels) cairo_rectangle(mCairo, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height); } -void gfxContext::Ellipse(gfxPoint center, gfxSize dimensions) +void +gfxContext::Ellipse(gfxPoint center, gfxSize dimensions) { // circle? if (dimensions.width == dimensions.height) { @@ -209,7 +229,8 @@ void gfxContext::Ellipse(gfxPoint center, gfxSize dimensions) } } -void gfxContext::Polygon(const gfxPoint *points, PRUint32 numPoints) +void +gfxContext::Polygon(const gfxPoint *points, PRUint32 numPoints) { if (numPoints == 0) return; @@ -220,7 +241,8 @@ void gfxContext::Polygon(const gfxPoint *points, PRUint32 numPoints) } } -void gfxContext::DrawSurface(gfxASurface *surface, gfxSize size) +void +gfxContext::DrawSurface(gfxASurface *surface, gfxSize size) { cairo_save(mCairo); cairo_set_source_surface(mCairo, surface->CairoSurface(), 0, 0); @@ -234,57 +256,70 @@ void gfxContext::DrawSurface(gfxASurface *surface, gfxSize size) } // transform stuff -void gfxContext::Translate(gfxPoint pt) +void +gfxContext::Translate(gfxPoint pt) { cairo_translate(mCairo, pt.x, pt.y); } -void gfxContext::Scale(gfxFloat x, gfxFloat y) + +void +gfxContext::Scale(gfxFloat x, gfxFloat y) { cairo_scale(mCairo, x, y); } -void gfxContext::Rotate(gfxFloat angle) + +void +gfxContext::Rotate(gfxFloat angle) { cairo_rotate(mCairo, angle); } -void gfxContext::Multiply(const gfxMatrix& matrix) + +void +gfxContext::Multiply(const gfxMatrix& matrix) { const cairo_matrix_t& mat = matrix.ToCairoMatrix(); cairo_transform(mCairo, &mat); } -void gfxContext::SetMatrix(const gfxMatrix& matrix) +void +gfxContext::SetMatrix(const gfxMatrix& matrix) { const cairo_matrix_t& mat = matrix.ToCairoMatrix(); cairo_set_matrix(mCairo, &mat); } -void gfxContext::IdentityMatrix() +void +gfxContext::IdentityMatrix() { cairo_identity_matrix(mCairo); } -gfxMatrix gfxContext::CurrentMatrix() const +gfxMatrix +gfxContext::CurrentMatrix() const { cairo_matrix_t mat; cairo_get_matrix(mCairo, &mat); return gfxMatrix(mat); } -gfxPoint gfxContext::DeviceToUser(gfxPoint point) const +gfxPoint +gfxContext::DeviceToUser(const gfxPoint& point) const { gfxPoint ret = point; cairo_device_to_user(mCairo, &ret.x, &ret.y); return ret; } -gfxSize gfxContext::DeviceToUser(gfxSize size) const +gfxSize +gfxContext::DeviceToUser(const gfxSize& size) const { gfxSize ret = size; cairo_device_to_user_distance(mCairo, &ret.width, &ret.height); return ret; } -gfxRect gfxContext::DeviceToUser(gfxRect rect) const +gfxRect +gfxContext::DeviceToUser(const gfxRect& rect) const { gfxRect ret = rect; cairo_device_to_user(mCairo, &ret.pos.x, &ret.pos.y); @@ -292,21 +327,24 @@ gfxRect gfxContext::DeviceToUser(gfxRect rect) const return ret; } -gfxPoint gfxContext::UserToDevice(gfxPoint point) const +gfxPoint +gfxContext::UserToDevice(const gfxPoint& point) const { gfxPoint ret = point; cairo_user_to_device(mCairo, &ret.x, &ret.y); return ret; } -gfxSize gfxContext::UserToDevice(gfxSize size) const +gfxSize +gfxContext::UserToDevice(const gfxSize& size) const { gfxSize ret = size; cairo_user_to_device_distance(mCairo, &ret.width, &ret.height); return ret; } -gfxRect gfxContext::UserToDevice(gfxRect rect) const +gfxRect +gfxContext::UserToDevice(const gfxRect& rect) const { gfxRect ret = rect; cairo_user_to_device(mCairo, &ret.pos.x, &ret.pos.y); @@ -314,7 +352,8 @@ gfxRect gfxContext::UserToDevice(gfxRect rect) const return ret; } -PRBool gfxContext::UserToDevicePixelSnapped(gfxRect& rect) const +PRBool +gfxContext::UserToDevicePixelSnapped(gfxRect& rect) const { // if we're not at 1.0 scale, don't snap cairo_matrix_t mat; @@ -335,8 +374,8 @@ PRBool gfxContext::UserToDevicePixelSnapped(gfxRect& rect) const p2.y != p4.y) return PR_FALSE; - p1.round(); - p2.round(); + p1.Round(); + p2.Round(); gfxPoint pd = p2 - p1; @@ -346,8 +385,9 @@ PRBool gfxContext::UserToDevicePixelSnapped(gfxRect& rect) const return PR_TRUE; } -void gfxContext::PixelSnappedRectangleAndSetPattern(const gfxRect& rect, - gfxPattern *pattern) +void +gfxContext::PixelSnappedRectangleAndSetPattern(const gfxRect& rect, + gfxPattern *pattern) { gfxRect r(rect); @@ -377,7 +417,8 @@ void gfxContext::PixelSnappedRectangleAndSetPattern(const gfxRect& rect, SetMatrix(mat); } -void gfxContext::SetAntialiasMode(AntialiasMode mode) +void +gfxContext::SetAntialiasMode(AntialiasMode mode) { if (mode == MODE_ALIASED) { cairo_set_antialias(mCairo, CAIRO_ANTIALIAS_NONE); @@ -386,7 +427,8 @@ void gfxContext::SetAntialiasMode(AntialiasMode mode) } } -gfxContext::AntialiasMode gfxContext::CurrentAntialiasMode() const +gfxContext::AntialiasMode +gfxContext::CurrentAntialiasMode() const { cairo_antialias_t aa = cairo_get_antialias(mCairo); if (aa == CAIRO_ANTIALIAS_NONE) @@ -394,7 +436,8 @@ gfxContext::AntialiasMode gfxContext::CurrentAntialiasMode() const return MODE_COVERAGE; } -void gfxContext::SetDash(gfxLineType ltype) +void +gfxContext::SetDash(gfxLineType ltype) { static double dash[] = {5.0, 5.0}; static double dot[] = {1.0, 1.0}; @@ -413,81 +456,102 @@ void gfxContext::SetDash(gfxLineType ltype) } } -void gfxContext::SetDash(gfxFloat *dashes, int ndash, gfxFloat offset) +void +gfxContext::SetDash(gfxFloat *dashes, int ndash, gfxFloat offset) { cairo_set_dash(mCairo, dashes, ndash, offset); } //void getDash() const; -void gfxContext::SetLineWidth(gfxFloat width) +void +gfxContext::SetLineWidth(gfxFloat width) { cairo_set_line_width(mCairo, width); } -gfxFloat gfxContext::CurrentLineWidth() const + +gfxFloat +gfxContext::CurrentLineWidth() const { return cairo_get_line_width(mCairo); } -void gfxContext::SetOperator(GraphicsOperator op) +void +gfxContext::SetOperator(GraphicsOperator op) { cairo_set_operator(mCairo, (cairo_operator_t)op); } -gfxContext::GraphicsOperator gfxContext::CurrentOperator() const + +gfxContext::GraphicsOperator +gfxContext::CurrentOperator() const { return (GraphicsOperator)cairo_get_operator(mCairo); } -void gfxContext::SetLineCap(GraphicsLineCap cap) +void +gfxContext::SetLineCap(GraphicsLineCap cap) { cairo_set_line_cap(mCairo, (cairo_line_cap_t)cap); } -gfxContext::GraphicsLineCap gfxContext::CurrentLineCap() const + +gfxContext::GraphicsLineCap +gfxContext::CurrentLineCap() const { return (GraphicsLineCap)cairo_get_line_cap(mCairo); } -void gfxContext::SetLineJoin(GraphicsLineJoin join) +void +gfxContext::SetLineJoin(GraphicsLineJoin join) { cairo_set_line_join(mCairo, (cairo_line_join_t)join); } -gfxContext::GraphicsLineJoin gfxContext::CurrentLineJoin() const + +gfxContext::GraphicsLineJoin +gfxContext::CurrentLineJoin() const { return (GraphicsLineJoin)cairo_get_line_join(mCairo); } - -void gfxContext::SetMiterLimit(gfxFloat limit) +void +gfxContext::SetMiterLimit(gfxFloat limit) { cairo_set_miter_limit(mCairo, limit); } -gfxFloat gfxContext::CurrentMiterLimit() const + +gfxFloat +gfxContext::CurrentMiterLimit() const { return cairo_get_miter_limit(mCairo); } // clipping -void gfxContext::Clip(gfxRect rect) +void +gfxContext::Clip(gfxRect rect) { cairo_new_path(mCairo); cairo_rectangle(mCairo, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height); cairo_clip(mCairo); } -void gfxContext::Clip(const gfxRegion& region) + +void +gfxContext::Clip(const gfxRegion& region) { } -void gfxContext::Clip() +void +gfxContext::Clip() { cairo_clip_preserve(mCairo); } -void gfxContext::ResetClip() +void +gfxContext::ResetClip() { cairo_reset_clip(mCairo); } -void gfxContext::UpdateSurfaceClip() +void +gfxContext::UpdateSurfaceClip() { NewPath(); Rectangle(gfxRect(0,0,0,0)); @@ -496,52 +560,62 @@ void gfxContext::UpdateSurfaceClip() // rendering sources -void gfxContext::SetColor(const gfxRGBA& c) +void +gfxContext::SetColor(const gfxRGBA& c) { cairo_set_source_rgba(mCairo, c.r, c.g, c.b, c.a); } -void gfxContext::SetPattern(gfxPattern *pattern) +void +gfxContext::SetPattern(gfxPattern *pattern) { cairo_set_source(mCairo, pattern->CairoPattern()); } -void gfxContext::SetSource(gfxASurface *surface, gfxPoint offset) +void +gfxContext::SetSource(gfxASurface *surface, gfxPoint offset) { cairo_set_source_surface(mCairo, surface->CairoSurface(), offset.x, offset.y); } // masking -void gfxContext::Mask(gfxPattern *pattern) +void +gfxContext::Mask(gfxPattern *pattern) { cairo_mask(mCairo, pattern->CairoPattern()); } -void gfxContext::Mask(gfxASurface *surface, gfxPoint offset) +void +gfxContext::Mask(gfxASurface *surface, gfxPoint offset) { cairo_mask_surface(mCairo, surface->CairoSurface(), offset.x, offset.y); } // fonts? -void gfxContext::DrawText(gfxTextRun& text) +void +gfxContext::DrawTextRun(gfxTextRun *text, gfxPoint pt) { - + if (text) + text->Draw(this, pt); } -void gfxContext::Paint(gfxFloat alpha) +void +gfxContext::Paint(gfxFloat alpha) { cairo_paint_with_alpha(mCairo, alpha); } // groups -void gfxContext::PushGroup(SurfaceContent content) +void +gfxContext::PushGroup(SurfaceContent content) { cairo_push_group_with_content(mCairo, (cairo_content_t) content); } -already_AddRefed gfxContext::PopGroup() +already_AddRefed +gfxContext::PopGroup() { cairo_pattern_t *pat = cairo_pop_group(mCairo); gfxPattern *wrapper = new gfxPattern(pat); @@ -549,30 +623,38 @@ already_AddRefed gfxContext::PopGroup() return wrapper; } -void gfxContext::PopGroupToSource() +void +gfxContext::PopGroupToSource() { cairo_pop_group_to_source(mCairo); } -void gfxContext::BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName) +void +gfxContext::BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName) { mSurface->BeginPrinting(aTitle, aPrintToFileName); } -void gfxContext::EndPrinting() +void +gfxContext::EndPrinting() { mSurface->EndPrinting(); } -void gfxContext::AbortPrinting() + +void +gfxContext::AbortPrinting() { mSurface->AbortPrinting(); } -void gfxContext::BeginPage() + +void +gfxContext::BeginPage() { mSurface->BeginPage(); } -void gfxContext::EndPage() +void +gfxContext::EndPage() { if (NS_FAILED(mSurface->EndPage())) cairo_show_page(mCairo);