| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2008, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 #include "third_party/skia/include/core/SkCanvas.h" | 41 #include "third_party/skia/include/core/SkCanvas.h" |
| 42 #include "third_party/skia/include/core/SkDevice.h" | 42 #include "third_party/skia/include/core/SkDevice.h" |
| 43 #include "third_party/skia/include/core/SkPaint.h" | 43 #include "third_party/skia/include/core/SkPaint.h" |
| 44 #include "third_party/skia/include/core/SkShader.h" | 44 #include "third_party/skia/include/core/SkShader.h" |
| 45 #include "third_party/skia/include/core/SkTemplates.h" | 45 #include "third_party/skia/include/core/SkTemplates.h" |
| 46 | 46 |
| 47 namespace WebCore { | 47 namespace WebCore { |
| 48 | 48 |
| 49 static void skiaDrawText(GraphicsContext* context, | 49 static void skiaDrawText(GraphicsContext* context, |
| 50 const SkPoint& point, | 50 const SkPoint& point, |
| 51 const SkRect& textRect, |
| 51 SkPaint* paint, | 52 SkPaint* paint, |
| 52 const WORD* glyphs, | 53 const WORD* glyphs, |
| 53 const int* advances, | 54 const int* advances, |
| 54 const GOFFSET* offsets, | 55 const GOFFSET* offsets, |
| 55 int numGlyphs) | 56 int numGlyphs) |
| 56 { | 57 { |
| 57 // Reserve space for 64 SkPoints on the stack. If numGlyphs is larger, the a
rray | 58 // Reserve space for 64 SkPoints on the stack. If numGlyphs is larger, the a
rray |
| 58 // will dynamically allocate it space for numGlyph glyphs. This is used to s
tore | 59 // will dynamically allocate it space for numGlyph glyphs. This is used to s
tore |
| 59 // the computed x,y locations. In the case where offsets==null, then we use
it | 60 // the computed x,y locations. In the case where offsets==null, then we use
it |
| 60 // to store (twice as many) SkScalars for x[] | 61 // to store (twice as many) SkScalars for x[] |
| 61 static const size_t kLocalGlyphMax = 64; | 62 static const size_t kLocalGlyphMax = 64; |
| 62 | 63 |
| 63 SkScalar x = point.fX; | 64 SkScalar x = point.fX; |
| 64 SkScalar y = point.fY; | 65 SkScalar y = point.fY; |
| 65 if (offsets) { | 66 if (offsets) { |
| 66 SkAutoSTArray<kLocalGlyphMax, SkPoint> storage(numGlyphs); | 67 SkAutoSTArray<kLocalGlyphMax, SkPoint> storage(numGlyphs); |
| 67 SkPoint* pos = storage.get(); | 68 SkPoint* pos = storage.get(); |
| 68 for (int i = 0; i < numGlyphs; i++) { | 69 for (int i = 0; i < numGlyphs; i++) { |
| 69 // GDI has dv go up, so we negate it | 70 // GDI has dv go up, so we negate it |
| 70 pos[i].set(x + SkIntToScalar(offsets[i].du), | 71 pos[i].set(x + SkIntToScalar(offsets[i].du), |
| 71 y + -SkIntToScalar(offsets[i].dv)); | 72 y + -SkIntToScalar(offsets[i].dv)); |
| 72 x += SkIntToScalar(advances[i]); | 73 x += SkIntToScalar(advances[i]); |
| 73 } | 74 } |
| 74 context->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, *paint); | 75 context->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, textRect
, *paint); |
| 75 } else { | 76 } else { |
| 76 SkAutoSTArray<kLocalGlyphMax * 2, SkScalar> storage(numGlyphs); | 77 SkAutoSTArray<kLocalGlyphMax * 2, SkScalar> storage(numGlyphs); |
| 77 SkScalar* xpos = storage.get(); | 78 SkScalar* xpos = storage.get(); |
| 78 for (int i = 0; i < numGlyphs; i++) { | 79 for (int i = 0; i < numGlyphs; i++) { |
| 79 xpos[i] = x; | 80 xpos[i] = x; |
| 80 x += SkIntToScalar(advances[i]); | 81 x += SkIntToScalar(advances[i]); |
| 81 } | 82 } |
| 82 context->drawPosTextH(glyphs, numGlyphs * sizeof(uint16_t), | 83 context->drawPosTextH(glyphs, numGlyphs * sizeof(uint16_t), |
| 83 xpos, y, *paint); | 84 xpos, y, textRect, *paint); |
| 84 } | 85 } |
| 85 } | 86 } |
| 86 | 87 |
| 87 static void setupPaintForFont(SkPaint* paint, GraphicsContext* context, | 88 static void setupPaintForFont(SkPaint* paint, GraphicsContext* context, |
| 88 SkTypeface* face, float size, uint32_t textFlags) | 89 SkTypeface* face, float size, uint32_t textFlags) |
| 89 { | 90 { |
| 90 paint->setTextSize(SkFloatToScalar(size)); | 91 paint->setTextSize(SkFloatToScalar(size)); |
| 91 paint->setTypeface(face); | 92 paint->setTypeface(face); |
| 92 | 93 |
| 93 if (!context->couldUseLCDRenderedText()) { | 94 if (!context->couldUseLCDRenderedText()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 111 flags |= textFlags; | 112 flags |= textFlags; |
| 112 paint->setFlags(flags); | 113 paint->setFlags(flags); |
| 113 } | 114 } |
| 114 | 115 |
| 115 static void paintSkiaText(GraphicsContext* context, HFONT hfont, | 116 static void paintSkiaText(GraphicsContext* context, HFONT hfont, |
| 116 SkTypeface* face, float size, uint32_t textFlags, | 117 SkTypeface* face, float size, uint32_t textFlags, |
| 117 int numGlyphs, | 118 int numGlyphs, |
| 118 const WORD* glyphs, | 119 const WORD* glyphs, |
| 119 const int* advances, | 120 const int* advances, |
| 120 const GOFFSET* offsets, | 121 const GOFFSET* offsets, |
| 121 const SkPoint* origin) | 122 const SkPoint& origin, |
| 123 const SkRect& textRect) |
| 122 { | 124 { |
| 123 TextDrawingModeFlags textMode = context->textDrawingModeSkia(); | 125 TextDrawingModeFlags textMode = context->textDrawingModeSkia(); |
| 124 // Ensure font load for printing, because PDF device needs it. | 126 // Ensure font load for printing, because PDF device needs it. |
| 125 if (context->isPrintingDevice()) | 127 if (context->isPrintingDevice()) |
| 126 FontPlatformData::ensureFontLoaded(hfont); | 128 FontPlatformData::ensureFontLoaded(hfont); |
| 127 | 129 |
| 128 // Filling (if necessary). This is the common case. | 130 // Filling (if necessary). This is the common case. |
| 129 SkPaint paint; | 131 SkPaint paint; |
| 130 context->setupPaintForFilling(&paint); | 132 context->setupPaintForFilling(&paint); |
| 131 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 133 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| 132 setupPaintForFont(&paint, context, face, size, textFlags); | 134 setupPaintForFont(&paint, context, face, size, textFlags); |
| 133 | 135 |
| 134 bool didFill = false; | 136 bool didFill = false; |
| 135 | 137 |
| 136 if ((textMode & TextModeFill) && (SkColorGetA(paint.getColor()) || paint.get
Looper())) { | 138 if ((textMode & TextModeFill) && (SkColorGetA(paint.getColor()) || paint.get
Looper())) { |
| 137 skiaDrawText(context, *origin, &paint, &glyphs[0], &advances[0], &offset
s[0], numGlyphs); | 139 skiaDrawText(context, origin, textRect, &paint, &glyphs[0], &advances[0]
, &offsets[0], numGlyphs); |
| 138 didFill = true; | 140 didFill = true; |
| 139 } | 141 } |
| 140 | 142 |
| 141 // Stroking on top (if necessary). | 143 // Stroking on top (if necessary). |
| 142 if ((textMode & TextModeStroke) | 144 if ((textMode & TextModeStroke) |
| 143 && context->strokeStyleSkia() != NoStroke | 145 && context->strokeStyleSkia() != NoStroke |
| 144 && context->strokeThicknessSkia() > 0) { | 146 && context->strokeThicknessSkia() > 0) { |
| 145 | 147 |
| 146 paint.reset(); | 148 paint.reset(); |
| 147 context->setupPaintForStroking(&paint, 0, 0); | 149 context->setupPaintForStroking(&paint, 0, 0); |
| 148 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 150 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| 149 setupPaintForFont(&paint, context, face, size, textFlags); | 151 setupPaintForFont(&paint, context, face, size, textFlags); |
| 150 | 152 |
| 151 if (didFill) { | 153 if (didFill) { |
| 152 // If there is a shadow and we filled above, there will already be | 154 // If there is a shadow and we filled above, there will already be |
| 153 // a shadow. We don't want to draw it again or it will be too dark | 155 // a shadow. We don't want to draw it again or it will be too dark |
| 154 // and it will go on top of the fill. | 156 // and it will go on top of the fill. |
| 155 // | 157 // |
| 156 // Note that this isn't strictly correct, since the stroke could be | 158 // Note that this isn't strictly correct, since the stroke could be |
| 157 // very thick and the shadow wouldn't account for this. The "right" | 159 // very thick and the shadow wouldn't account for this. The "right" |
| 158 // thing would be to draw to a new layer and then draw that layer | 160 // thing would be to draw to a new layer and then draw that layer |
| 159 // with a shadow. But this is a lot of extra work for something | 161 // with a shadow. But this is a lot of extra work for something |
| 160 // that isn't normally an issue. | 162 // that isn't normally an issue. |
| 161 paint.setLooper(0); | 163 paint.setLooper(0); |
| 162 } | 164 } |
| 163 | 165 |
| 164 skiaDrawText(context, *origin, &paint, &glyphs[0], &advances[0], &offset
s[0], numGlyphs); | 166 skiaDrawText(context, origin, textRect, &paint, &glyphs[0], &advances[0]
, &offsets[0], numGlyphs); |
| 165 } | 167 } |
| 166 } | 168 } |
| 167 | 169 |
| 168 ////////////////////////////////////////////////////////////////////////////////
/////////// | 170 ////////////////////////////////////////////////////////////////////////////////
/////////// |
| 169 | 171 |
| 170 void paintSkiaText(GraphicsContext* context, | 172 void paintSkiaText(GraphicsContext* context, |
| 171 const FontPlatformData& data, | 173 const FontPlatformData& data, |
| 172 int numGlyphs, | 174 int numGlyphs, |
| 173 const WORD* glyphs, | 175 const WORD* glyphs, |
| 174 const int* advances, | 176 const int* advances, |
| 175 const GOFFSET* offsets, | 177 const GOFFSET* offsets, |
| 176 const SkPoint* origin) | 178 const SkPoint& origin, |
| 179 const SkRect& textRect) |
| 177 { | 180 { |
| 178 paintSkiaText(context, data.hfont(), data.typeface(), data.size(), data.pain
tTextFlags(), | 181 paintSkiaText(context, data.hfont(), data.typeface(), data.size(), data.pain
tTextFlags(), |
| 179 numGlyphs, glyphs, advances, offsets, origin); | 182 numGlyphs, glyphs, advances, offsets, origin, textRect); |
| 180 } | 183 } |
| 181 | 184 |
| 182 void paintSkiaText(GraphicsContext* context, | 185 void paintSkiaText(GraphicsContext* context, |
| 183 HFONT hfont, | 186 HFONT hfont, |
| 184 int numGlyphs, | 187 int numGlyphs, |
| 185 const WORD* glyphs, | 188 const WORD* glyphs, |
| 186 const int* advances, | 189 const int* advances, |
| 187 const GOFFSET* offsets, | 190 const GOFFSET* offsets, |
| 188 const SkPoint* origin) | 191 const SkPoint& origin, |
| 192 const SkRect& textRect) |
| 189 { | 193 { |
| 190 int size; | 194 int size; |
| 191 int paintTextFlags; | 195 int paintTextFlags; |
| 192 SkTypeface* face = CreateTypefaceFromHFont(hfont, &size, &paintTextFlags); | 196 SkTypeface* face = CreateTypefaceFromHFont(hfont, &size, &paintTextFlags); |
| 193 SkAutoUnref aur(face); | 197 SkAutoUnref aur(face); |
| 194 | 198 |
| 195 paintSkiaText(context, hfont, face, size, paintTextFlags, numGlyphs, glyphs,
advances, offsets, origin); | 199 paintSkiaText(context, hfont, face, size, paintTextFlags, numGlyphs, glyphs,
advances, offsets, origin, textRect); |
| 196 } | 200 } |
| 197 | 201 |
| 198 } // namespace WebCore | 202 } // namespace WebCore |
| OLD | NEW |