Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/include/fxge/fx_ge.h" | 5 #include "core/include/fxge/fx_ge.h" |
| 6 | 6 |
| 7 #if defined(_SKIA_SUPPORT_) | 7 #if defined(_SKIA_SUPPORT_) |
| 8 #include "core/include/fxcodec/fx_codec.h" | 8 #include "core/include/fxcodec/fx_codec.h" |
| 9 | 9 |
| 10 #include "core/src/fxge/agg/fx_agg_driver.h" | 10 #include "core/src/fxge/agg/fx_agg_driver.h" |
| 11 #include "core/src/fxge/skia/fx_skia_device.h" | 11 #include "core/src/fxge/skia/fx_skia_device.h" |
| 12 | 12 |
| 13 #include "SkCanvas.h" | 13 #include "third_party/skia/include/core/SkCanvas.h" |
| 14 #include "SkDashPathEffect.h" | 14 #include "third_party/skia/include/core/SkColorPriv.h" |
| 15 #include "SkPaint.h" | 15 #include "third_party/skia/include/core/SkPaint.h" |
| 16 #include "SkPath.h" | 16 #include "third_party/skia/include/core/SkPath.h" |
| 17 #include "third_party/skia/include/core/SkPictureRecorder.h" | |
| 18 #include "third_party/skia/include/core/SkStream.h" | |
| 19 #include "third_party/skia/include/core/SkTypeface.h" | |
| 20 #include "third_party/skia/include/effects/SkDashPathEffect.h" | |
| 21 | |
| 22 #define SHOW_SKIA_PATH 0 // set to 1 to print the path contents | |
| 23 #define DRAW_SKIA_CLIP 0 // set to 1 to draw a green rectangle around the clip | |
| 24 | |
| 25 static void DebugShowSkiaPath(const SkPath& path) { | |
| 26 #if SHOW_SKIA_PATH | |
| 27 char buffer[4096]; | |
| 28 sk_bzero(buffer, sizeof(buffer)); | |
| 29 SkMemoryWStream stream(buffer, sizeof(buffer)); | |
| 30 path.dump(&stream, false, false); | |
| 31 printf("%s\n", buffer); | |
| 32 #endif // SHOW_SKIA_PATH | |
| 33 } | |
| 34 | |
| 35 #if DRAW_SKIA_CLIP | |
| 36 | |
| 37 static SkPaint DebugClipPaint() { | |
| 38 SkPaint paint; | |
| 39 paint.setAntiAlias(true); | |
| 40 paint.setColor(SK_ColorGREEN); | |
| 41 paint.setStyle(SkPaint::kStroke_Style); | |
| 42 return paint; | |
| 43 } | |
| 44 | |
| 45 static void DebugDrawSkiaClipRect(SkCanvas* canvas, const SkRect& rect) { | |
| 46 SkPaint paint = DebugClipPaint(); | |
| 47 canvas->drawRect(rect, paint); | |
| 48 } | |
| 49 | |
| 50 static void DebugDrawSkiaClipPath(SkCanvas* canvas, const SkPath& path) { | |
| 51 SkPaint paint = DebugClipPaint(); | |
| 52 canvas->drawPath(path, paint); | |
| 53 } | |
| 54 | |
| 55 #else // DRAW_SKIA_CLIP | |
| 56 | |
| 57 static void DebugDrawSkiaClipRect(SkCanvas* canvas, const SkRect& rect) {} | |
| 58 static void DebugDrawSkiaClipPath(SkCanvas* canvas, const SkPath& path) {} | |
| 59 | |
| 60 #endif // DRAW_SKIA_CLIP | |
| 61 | |
| 62 #undef SHOW_SKIA_PATH | |
| 63 #undef DRAW_SKIA_CLIP | |
| 17 | 64 |
| 18 static SkPath BuildPath(const CFX_PathData* pPathData, | 65 static SkPath BuildPath(const CFX_PathData* pPathData, |
| 19 const CFX_Matrix* pObject2Device) { | 66 const CFX_Matrix* pObject2Device) { |
| 20 SkPath skPath; | 67 SkPath skPath; |
| 21 const CFX_PathData* pFPath = pPathData; | 68 const CFX_PathData* pFPath = pPathData; |
| 22 int nPoints = pFPath->GetPointCount(); | 69 int nPoints = pFPath->GetPointCount(); |
| 23 FX_PATHPOINT* pPoints = pFPath->GetPoints(); | 70 FX_PATHPOINT* pPoints = pFPath->GetPoints(); |
| 24 for (int i = 0; i < nPoints; i++) { | 71 for (int i = 0; i < nPoints; i++) { |
| 25 FX_FLOAT x = pPoints[i].m_PointX; | 72 FX_FLOAT x = pPoints[i].m_PointX; |
| 26 FX_FLOAT y = pPoints[i].m_PointY; | 73 FX_FLOAT y = pPoints[i].m_PointY; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 off = 0; | 138 off = 0; |
| 92 intervals[i * 2] = on; | 139 intervals[i * 2] = on; |
| 93 intervals[i * 2 + 1] = off; | 140 intervals[i * 2 + 1] = off; |
| 94 } | 141 } |
| 95 spaint | 142 spaint |
| 96 ->setPathEffect(SkDashPathEffect::Create(intervals, count * 2, | 143 ->setPathEffect(SkDashPathEffect::Create(intervals, count * 2, |
| 97 pGraphState->m_DashPhase)) | 144 pGraphState->m_DashPhase)) |
| 98 ->unref(); | 145 ->unref(); |
| 99 } | 146 } |
| 100 spaint->setStyle(SkPaint::kStroke_Style); | 147 spaint->setStyle(SkPaint::kStroke_Style); |
| 101 spaint->setAntiAlias(TRUE); | 148 spaint->setAntiAlias(true); |
| 102 spaint->setStrokeWidth(width); | 149 spaint->setStrokeWidth(width); |
| 103 spaint->setStrokeMiter(pGraphState->m_MiterLimit); | 150 spaint->setStrokeMiter(pGraphState->m_MiterLimit); |
| 104 spaint->setStrokeCap(cap); | 151 spaint->setStrokeCap(cap); |
| 105 spaint->setStrokeJoin(join); | 152 spaint->setStrokeJoin(join); |
| 106 } | 153 } |
| 107 | 154 |
| 108 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap, | 155 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap, |
| 109 int dither_bits, | 156 int dither_bits, |
| 110 FX_BOOL bRgbByteOrder, | 157 FX_BOOL bRgbByteOrder, |
| 111 CFX_DIBitmap* pOriDevice, | 158 CFX_DIBitmap* pOriDevice, |
| 112 FX_BOOL bGroupKnockout) { | 159 FX_BOOL bGroupKnockout) { |
| 113 m_pAggDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, | 160 m_pAggDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, |
| 114 pOriDevice, bGroupKnockout); | 161 pOriDevice, bGroupKnockout); |
| 115 SkBitmap skBitmap; | 162 SkBitmap skBitmap; |
| 116 const CFX_DIBitmap* bitmap = m_pAggDriver->m_pBitmap; | 163 const CFX_DIBitmap* bitmap = m_pAggDriver->GetBitmap(); |
| 117 SkImageInfo imageInfo = | 164 SkImageInfo imageInfo = |
| 118 SkImageInfo::Make(bitmap->GetWidth(), bitmap->GetHeight(), | 165 SkImageInfo::Make(bitmap->GetWidth(), bitmap->GetHeight(), |
| 119 kN32_SkColorType, kOpaque_SkAlphaType); | 166 kN32_SkColorType, kOpaque_SkAlphaType); |
| 120 skBitmap.installPixels(imageInfo, bitmap->GetBuffer(), bitmap->GetPitch(), | 167 skBitmap.installPixels(imageInfo, bitmap->GetBuffer(), bitmap->GetPitch(), |
| 121 nullptr, /* to do : set color table */ | 168 nullptr, /* to do : set color table */ |
| 122 nullptr, nullptr); | 169 nullptr, nullptr); |
| 123 m_canvas = new SkCanvas(skBitmap); | 170 m_pCanvas = new SkCanvas(skBitmap); |
| 171 m_ditherBits = dither_bits; | |
| 172 m_pRecorder = nullptr; | |
| 173 } | |
| 174 | |
| 175 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(int size_x, int size_y) { | |
| 176 m_pAggDriver = nullptr; | |
| 177 m_pRecorder = new SkPictureRecorder; | |
| 178 m_pRecorder->beginRecording(SkIntToScalar(size_x), SkIntToScalar(size_y)); | |
| 179 m_pCanvas = m_pRecorder->getRecordingCanvas(); | |
| 180 m_ditherBits = 0; | |
| 181 } | |
| 182 | |
| 183 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(SkPictureRecorder* recorder) { | |
| 184 m_pAggDriver = nullptr; | |
| 185 m_pRecorder = recorder; | |
| 186 m_pCanvas = m_pRecorder->getRecordingCanvas(); | |
| 187 m_ditherBits = 0; | |
| 124 } | 188 } |
| 125 | 189 |
| 126 CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() { | 190 CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() { |
| 127 #if 0 // TODO(caryclark) : mismatch on allocator ? | 191 if (!m_pRecorder) |
| 128 delete m_canvas; | 192 delete m_pCanvas; |
| 129 #endif | |
| 130 delete m_pAggDriver; | 193 delete m_pAggDriver; |
| 131 } | 194 } |
| 132 | 195 |
| 133 FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, | 196 FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, |
| 134 const FXTEXT_CHARPOS* pCharPos, | 197 const FXTEXT_CHARPOS* pCharPos, |
| 135 CFX_Font* pFont, | 198 CFX_Font* pFont, |
| 136 CFX_FontCache* pCache, | 199 CFX_FontCache* pCache, |
| 137 const CFX_Matrix* pObject2Device, | 200 const CFX_Matrix* pObject2Device, |
| 138 FX_FLOAT font_size, | 201 FX_FLOAT font_size, |
| 139 FX_DWORD color, | 202 FX_DWORD color, |
| 140 int alpha_flag, | 203 int alpha_flag, |
| 141 void* pIccTransform) { | 204 void* pIccTransform) { |
| 142 return m_pAggDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, | 205 SkAutoTUnref<SkTypeface> typeface(SkTypeface::CreateFromStream( |
| 143 pObject2Device, font_size, color, | 206 new SkMemoryStream(pFont->GetFontData(), pFont->GetSize()))); |
| 144 alpha_flag, pIccTransform); | 207 SkPaint paint; |
| 208 paint.setAntiAlias(true); | |
| 209 paint.setColor(color); | |
| 210 paint.setTypeface(typeface); | |
| 211 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | |
| 212 paint.setTextSize(font_size); | |
| 213 m_pCanvas->save(); | |
| 214 SkMatrix skMatrix; | |
| 215 const CFX_Matrix& m = *pObject2Device; | |
| 216 // note that PDF's y-axis goes up; Skia's y-axis goes down | |
| 217 skMatrix.setAll(m.a, m.b, m.e, -m.c, -m.d, m.f, 0, 0, 1); | |
| 218 m_pCanvas->concat(skMatrix); | |
| 219 for (int index = 0; index < nChars; ++index) { | |
| 220 const FXTEXT_CHARPOS& cp = pCharPos[index]; | |
| 221 uint16_t glyph = (uint16_t)cp.m_GlyphIndex; | |
| 222 m_pCanvas->drawText(&glyph, 2, cp.m_OriginX, cp.m_OriginY, paint); | |
| 223 } | |
| 224 m_pCanvas->restore(); | |
| 225 return TRUE; | |
| 145 } | 226 } |
| 146 | 227 |
| 147 int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) { | 228 int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) { |
| 148 return m_pAggDriver->GetDeviceCaps(caps_id); | 229 switch (caps_id) { |
| 230 case FXDC_DEVICE_CLASS: | |
| 231 return FXDC_DISPLAY; | |
| 232 case FXDC_PIXEL_WIDTH: | |
| 233 return m_pCanvas->imageInfo().width(); | |
| 234 case FXDC_PIXEL_HEIGHT: | |
| 235 return m_pCanvas->imageInfo().height(); | |
| 236 case FXDC_BITS_PIXEL: | |
| 237 return 32; | |
| 238 case FXDC_HORZ_SIZE: | |
| 239 case FXDC_VERT_SIZE: | |
| 240 return 0; | |
| 241 case FXDC_RENDER_CAPS: | |
| 242 return FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | | |
| 243 FXRC_BLEND_MODE | FXRC_SOFT_CLIP | FXRC_ALPHA_OUTPUT; | |
| 244 case FXDC_DITHER_BITS: | |
| 245 return m_ditherBits; | |
| 246 } | |
| 247 return 0; | |
| 149 } | 248 } |
| 150 | 249 |
| 151 void CFX_SkiaDeviceDriver::SaveState() { | 250 void CFX_SkiaDeviceDriver::SaveState() { |
| 152 m_canvas->save(); | 251 m_pCanvas->save(); |
| 153 m_pAggDriver->SaveState(); | 252 if (m_pAggDriver) |
| 253 m_pAggDriver->SaveState(); | |
| 154 } | 254 } |
| 155 | 255 |
| 156 void CFX_SkiaDeviceDriver::RestoreState(FX_BOOL bKeepSaved) { | 256 void CFX_SkiaDeviceDriver::RestoreState(FX_BOOL bKeepSaved) { |
| 157 m_pAggDriver->RestoreState(bKeepSaved); | 257 if (m_pAggDriver) |
| 158 m_canvas->restore(); | 258 m_pAggDriver->RestoreState(bKeepSaved); |
| 259 m_pCanvas->restore(); | |
| 260 if (bKeepSaved) | |
| 261 m_pCanvas->save(); | |
| 159 } | 262 } |
| 160 | 263 |
| 161 void CFX_SkiaDeviceDriver::SetClipMask( | 264 void CFX_SkiaDeviceDriver::SetClipMask( |
| 162 agg::rasterizer_scanline_aa& rasterizer) { | 265 agg::rasterizer_scanline_aa& rasterizer) { |
| 163 m_pAggDriver->SetClipMask(rasterizer); | 266 if (m_pAggDriver) |
| 267 m_pAggDriver->SetClipMask(rasterizer); | |
| 164 } | 268 } |
| 165 | 269 |
| 166 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill( | 270 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill( |
| 167 const CFX_PathData* pPathData, // path info | 271 const CFX_PathData* pPathData, // path info |
| 168 const CFX_Matrix* pObject2Device, // optional transformation | 272 const CFX_Matrix* pObject2Device, // flips object's y-axis |
| 169 int fill_mode // fill mode, WINDING or ALTERNATE | 273 int fill_mode // fill mode, WINDING or ALTERNATE |
| 170 ) { | 274 ) { |
| 171 if (!m_pAggDriver->m_pClipRgn) { | |
| 172 m_pAggDriver->m_pClipRgn = new CFX_ClipRgn( | |
| 173 GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); | |
| 174 } | |
| 175 | |
| 176 if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { | 275 if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { |
| 177 CFX_FloatRect rectf; | 276 CFX_FloatRect rectf; |
| 178 if (pPathData->IsRect(pObject2Device, &rectf)) { | 277 if (pPathData->IsRect(pObject2Device, &rectf)) { |
| 179 rectf.Intersect( | 278 rectf.Intersect( |
| 180 CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), | 279 CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), |
| 181 (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); | 280 (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); |
| 182 FX_RECT rect = rectf.GetOutterRect(); | 281 FX_RECT rect = rectf.GetOutterRect(); |
| 183 m_pAggDriver->m_pClipRgn->IntersectRect(rect); | 282 // note that PDF's y-axis goes up; Skia's y-axis goes down |
| 283 SkRect skClipRect = | |
| 284 SkRect::MakeLTRB(rectf.left, rectf.bottom, rectf.right, rectf.top); | |
| 285 DebugDrawSkiaClipRect(m_pCanvas, skClipRect); | |
| 286 m_pCanvas->clipRect(skClipRect); | |
| 184 return TRUE; | 287 return TRUE; |
| 185 } | 288 } |
| 186 } | 289 } |
| 187 SkPath clip = BuildPath(pPathData, pObject2Device); | 290 SkPath skClipPath = BuildPath(pPathData, pObject2Device); |
| 188 clip.setFillType((fill_mode & 3) == FXFILL_WINDING | 291 skClipPath.setFillType((fill_mode & 3) == FXFILL_WINDING |
| 189 ? SkPath::kWinding_FillType | 292 ? SkPath::kWinding_FillType |
| 190 : SkPath::kEvenOdd_FillType); | 293 : SkPath::kEvenOdd_FillType); |
| 191 const CFX_Matrix& m = *pObject2Device; | 294 DebugShowSkiaPath(skClipPath); |
| 192 #if 0 | 295 DebugDrawSkiaClipPath(m_pCanvas, skClipPath); |
| 193 // TODO(caryclark) : don't clip quite yet | 296 m_pCanvas->clipPath(skClipPath); |
| 194 // need to understand how to save/restore to balance the clip | |
| 195 printf("m:(%g,%g,%g) (%g,%g,%g)\n", m.a, m.b, m.c, m.d, m.e, m.f); | |
| 196 clip.dump(); | |
| 197 SkMatrix skMatrix; | |
| 198 skMatrix.setAll(m.a, m.b, m.c, m.d, m.e, m.f, 0, 0, 1); | |
| 199 m_canvas->setMatrix(skMatrix); | |
| 200 m_canvas->clipPath(clip, SkRegion::kReplace_Op); | |
| 201 #endif | |
| 202 | 297 |
| 203 return TRUE; | 298 return TRUE; |
| 204 } | 299 } |
| 205 | 300 |
| 206 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke( | 301 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke( |
| 207 const CFX_PathData* pPathData, // path info | 302 const CFX_PathData* pPathData, // path info |
| 208 const CFX_Matrix* pObject2Device, // optional transformation | 303 const CFX_Matrix* pObject2Device, // optional transformation |
| 209 const CFX_GraphStateData* pGraphState // graphic state, for pen attributes | 304 const CFX_GraphStateData* pGraphState // graphic state, for pen attributes |
| 210 ) { | 305 ) { |
| 211 if (!m_pAggDriver->m_pClipRgn) { | |
| 212 m_pAggDriver->m_pClipRgn = new CFX_ClipRgn( | |
| 213 GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); | |
| 214 } | |
| 215 | |
| 216 // build path data | 306 // build path data |
| 217 SkPath skPath = BuildPath(pPathData, NULL); | 307 SkPath skPath = BuildPath(pPathData, NULL); |
| 218 skPath.setFillType(SkPath::kWinding_FillType); | 308 skPath.setFillType(SkPath::kWinding_FillType); |
| 219 | 309 |
| 220 SkPaint spaint; | 310 SkPaint spaint; |
| 221 PaintStroke(&spaint, pGraphState); | 311 PaintStroke(&spaint, pGraphState); |
| 222 SkPath dst_path; | 312 SkPath dst_path; |
| 223 spaint.getFillPath(skPath, &dst_path); | 313 spaint.getFillPath(skPath, &dst_path); |
| 224 #if 01 | 314 DebugDrawSkiaClipPath(m_pCanvas, dst_path); |
| 225 SkMatrix skMatrix; | 315 m_pCanvas->clipPath(dst_path); |
| 226 const CFX_Matrix& m = *pObject2Device; | |
| 227 skMatrix.setAll(m.a, m.b, m.c, m.d, m.e, m.f, 0, 0, 1); | |
| 228 m_canvas->setMatrix(skMatrix); | |
| 229 // TODO(caryclark) : don't clip quite yet | |
| 230 // need to understand how to save/restore so that clip is later undone | |
| 231 m_canvas->clipPath(dst_path, SkRegion::kReplace_Op); | |
| 232 #endif | |
| 233 return TRUE; | 316 return TRUE; |
| 234 } | 317 } |
| 235 | 318 |
| 236 FX_BOOL CFX_SkiaDeviceDriver::RenderRasterizer( | 319 FX_BOOL CFX_SkiaDeviceDriver::RenderRasterizer( |
| 237 agg::rasterizer_scanline_aa& rasterizer, | 320 agg::rasterizer_scanline_aa& rasterizer, |
| 238 FX_DWORD color, | 321 FX_DWORD color, |
| 239 FX_BOOL bFullCover, | 322 FX_BOOL bFullCover, |
| 240 FX_BOOL bGroupKnockout, | 323 FX_BOOL bGroupKnockout, |
| 241 int alpha_flag, | 324 int alpha_flag, |
| 242 void* pIccTransform) { | 325 void* pIccTransform) { |
| 243 return m_pAggDriver->RenderRasterizer( | 326 return m_pAggDriver && |
| 244 rasterizer, color, bFullCover, bGroupKnockout, alpha_flag, pIccTransform); | 327 m_pAggDriver->RenderRasterizer(rasterizer, color, bFullCover, |
| 328 bGroupKnockout, alpha_flag, | |
| 329 pIccTransform); | |
| 245 } | 330 } |
| 246 | 331 |
| 247 FX_BOOL CFX_SkiaDeviceDriver::DrawPath( | 332 FX_BOOL CFX_SkiaDeviceDriver::DrawPath( |
| 248 const CFX_PathData* pPathData, // path info | 333 const CFX_PathData* pPathData, // path info |
| 249 const CFX_Matrix* pObject2Device, // optional transformation | 334 const CFX_Matrix* pObject2Device, // optional transformation |
| 250 const CFX_GraphStateData* pGraphState, // graphic state, for pen attributes | 335 const CFX_GraphStateData* pGraphState, // graphic state, for pen attributes |
| 251 FX_DWORD fill_color, // fill color | 336 FX_DWORD fill_color, // fill color |
| 252 FX_DWORD stroke_color, // stroke color | 337 FX_DWORD stroke_color, // stroke color |
| 253 int fill_mode, // fill mode, WINDING or ALTERNATE. 0 for not filled | 338 int fill_mode, // fill mode, WINDING or ALTERNATE. 0 for not filled |
| 254 int alpha_flag, | 339 int alpha_flag, |
| 255 void* pIccTransform, | 340 void* pIccTransform, |
| 256 int blend_type) { | 341 int blend_type) { |
| 257 if (!GetBuffer()) | |
| 258 return TRUE; | |
| 259 SkIRect rect; | 342 SkIRect rect; |
| 260 rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH), | 343 rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH), |
| 261 GetDeviceCaps(FXDC_PIXEL_HEIGHT)); | 344 GetDeviceCaps(FXDC_PIXEL_HEIGHT)); |
| 262 SkPath skPath = BuildPath(pPathData, pObject2Device); | 345 SkPath skPath = BuildPath(pPathData, pObject2Device); |
| 263 SkPaint spaint; | 346 SkPaint spaint; |
| 264 spaint.setAntiAlias(TRUE); | 347 spaint.setAntiAlias(true); |
| 265 if ((fill_mode & 3) && fill_color) { | 348 if ((fill_mode & 3) && fill_color) { |
| 266 skPath.setFillType((fill_mode & 3) == FXFILL_WINDING | 349 skPath.setFillType((fill_mode & 3) == FXFILL_WINDING |
| 267 ? SkPath::kWinding_FillType | 350 ? SkPath::kWinding_FillType |
| 268 : SkPath::kEvenOdd_FillType); | 351 : SkPath::kEvenOdd_FillType); |
| 269 | 352 |
| 270 spaint.setStyle(SkPaint::kFill_Style); | 353 spaint.setStyle(SkPaint::kFill_Style); |
| 271 spaint.setColor(fill_color); | 354 spaint.setColor(fill_color); |
| 272 m_canvas->drawPath(skPath, spaint); | 355 m_pCanvas->drawPath(skPath, spaint); |
| 273 } | 356 } |
| 274 int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) | 357 int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) |
| 275 ? FXGETFLAG_ALPHA_STROKE(alpha_flag) | 358 ? FXGETFLAG_ALPHA_STROKE(alpha_flag) |
| 276 : FXARGB_A(stroke_color); | 359 : FXARGB_A(stroke_color); |
| 277 | 360 |
| 278 if (pGraphState && stroke_alpha) { | 361 if (pGraphState && stroke_alpha) { |
| 279 spaint.setColor(stroke_color); | 362 spaint.setColor(stroke_color); |
| 280 PaintStroke(&spaint, pGraphState); | 363 PaintStroke(&spaint, pGraphState); |
| 281 m_canvas->drawPath(skPath, spaint); | 364 m_pCanvas->drawPath(skPath, spaint); |
| 282 } | 365 } |
| 283 | 366 |
| 284 return TRUE; | 367 return TRUE; |
| 285 } | 368 } |
| 286 | 369 |
| 287 FX_BOOL CFX_SkiaDeviceDriver::SetPixel(int x, | 370 FX_BOOL CFX_SkiaDeviceDriver::SetPixel(int x, |
| 288 int y, | 371 int y, |
| 289 FX_DWORD color, | 372 FX_DWORD color, |
| 290 int alpha_flag, | 373 int alpha_flag, |
| 291 void* pIccTransform) { | 374 void* pIccTransform) { |
| 292 return m_pAggDriver->SetPixel(x, y, color, alpha_flag, pIccTransform); | 375 return m_pAggDriver && |
| 376 m_pAggDriver->SetPixel(x, y, color, alpha_flag, pIccTransform); | |
| 293 } | 377 } |
| 294 | 378 |
| 295 FX_BOOL CFX_SkiaDeviceDriver::FillRect(const FX_RECT* pRect, | 379 FX_BOOL CFX_SkiaDeviceDriver::FillRect(const FX_RECT* pRect, |
| 296 FX_DWORD fill_color, | 380 FX_DWORD fill_color, |
| 297 int alpha_flag, | 381 int alpha_flag, |
| 298 void* pIccTransform, | 382 void* pIccTransform, |
| 299 int blend_type) { | 383 int blend_type) { |
| 300 SkPaint spaint; | 384 SkPaint spaint; |
| 301 spaint.setAntiAlias(true); | 385 spaint.setAntiAlias(true); |
| 302 spaint.setColor(fill_color); | 386 spaint.setColor(fill_color); |
| 303 | 387 |
| 304 m_canvas->drawRect( | 388 m_pCanvas->drawRect( |
| 305 SkRect::MakeLTRB(pRect->left, pRect->top, pRect->right, pRect->bottom), | 389 SkRect::MakeLTRB(pRect->left, pRect->top, pRect->right, pRect->bottom), |
| 306 spaint); | 390 spaint); |
| 307 return TRUE; | 391 return TRUE; |
| 308 } | 392 } |
| 309 | 393 |
| 310 FX_BOOL CFX_SkiaDeviceDriver::GetClipBox(FX_RECT* pRect) { | 394 FX_BOOL CFX_SkiaDeviceDriver::GetClipBox(FX_RECT* pRect) { |
| 311 return m_pAggDriver->GetClipBox(pRect); | 395 // TODO(caryclark) call m_canvas->getClipDeviceBounds() instead |
| 396 pRect->left = 0; | |
| 397 pRect->top = 0; | |
| 398 const SkImageInfo& canvasSize = m_pCanvas->imageInfo(); | |
| 399 pRect->right = canvasSize.width(); | |
| 400 pRect->bottom = canvasSize.height(); | |
| 401 return TRUE; | |
| 312 } | 402 } |
| 313 | 403 |
| 314 FX_BOOL CFX_SkiaDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, | 404 FX_BOOL CFX_SkiaDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, |
| 315 int left, | 405 int left, |
| 316 int top, | 406 int top, |
| 317 void* pIccTransform, | 407 void* pIccTransform, |
| 318 FX_BOOL bDEdge) { | 408 FX_BOOL bDEdge) { |
| 319 return m_pAggDriver->GetDIBits(pBitmap, left, top, pIccTransform, bDEdge); | 409 return m_pAggDriver && |
| 410 m_pAggDriver->GetDIBits(pBitmap, left, top, pIccTransform, bDEdge); | |
| 320 } | 411 } |
| 321 | 412 |
| 322 FX_BOOL CFX_SkiaDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, | 413 FX_BOOL CFX_SkiaDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, |
| 323 FX_DWORD argb, | 414 FX_DWORD argb, |
| 324 const FX_RECT* pSrcRect, | 415 const FX_RECT* pSrcRect, |
| 325 int left, | 416 int left, |
| 326 int top, | 417 int top, |
| 327 int blend_type, | 418 int blend_type, |
| 328 int alpha_flag, | 419 int alpha_flag, |
| 329 void* pIccTransform) { | 420 void* pIccTransform) { |
| 330 return m_pAggDriver->SetDIBits(pBitmap, argb, pSrcRect, left, top, blend_type, | 421 return m_pAggDriver && |
| 422 m_pAggDriver->SetDIBits(pBitmap, argb, pSrcRect, left, top, blend_type, | |
| 331 alpha_flag, pIccTransform); | 423 alpha_flag, pIccTransform); |
| 332 } | 424 } |
| 333 | 425 |
| 334 FX_BOOL CFX_SkiaDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource, | 426 FX_BOOL CFX_SkiaDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource, |
| 335 FX_DWORD argb, | 427 FX_DWORD argb, |
| 336 int dest_left, | 428 int dest_left, |
| 337 int dest_top, | 429 int dest_top, |
| 338 int dest_width, | 430 int dest_width, |
| 339 int dest_height, | 431 int dest_height, |
| 340 const FX_RECT* pClipRect, | 432 const FX_RECT* pClipRect, |
| 341 FX_DWORD flags, | 433 FX_DWORD flags, |
| 342 int alpha_flag, | 434 int alpha_flag, |
| 343 void* pIccTransform, | 435 void* pIccTransform, |
| 344 int blend_type) { | 436 int blend_type) { |
| 345 return m_pAggDriver->StretchDIBits(pSource, argb, dest_left, dest_top, | 437 return m_pAggDriver && |
| 438 m_pAggDriver->StretchDIBits(pSource, argb, dest_left, dest_top, | |
| 346 dest_width, dest_height, pClipRect, flags, | 439 dest_width, dest_height, pClipRect, flags, |
| 347 alpha_flag, pIccTransform, blend_type); | 440 alpha_flag, pIccTransform, blend_type); |
| 348 } | 441 } |
| 349 | 442 |
| 350 FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, | 443 FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, |
| 351 int bitmap_alpha, | 444 int bitmap_alpha, |
| 352 FX_DWORD argb, | 445 FX_DWORD argb, |
| 353 const CFX_Matrix* pMatrix, | 446 const CFX_Matrix* pMatrix, |
| 354 FX_DWORD render_flags, | 447 FX_DWORD render_flags, |
| 355 void*& handle, | 448 void*& handle, |
| 356 int alpha_flag, | 449 int alpha_flag, |
| 357 void* pIccTransform, | 450 void* pIccTransform, |
| 358 int blend_type) { | 451 int blend_type) { |
| 359 return m_pAggDriver->StartDIBits(pSource, bitmap_alpha, argb, pMatrix, | 452 SkColorType colorType; |
| 360 render_flags, handle, alpha_flag, | 453 const uint8_t* buffer = pSource->GetBuffer(); |
| 361 pIccTransform, blend_type); | 454 std::unique_ptr<uint8_t[]> dstStorage; |
| 455 int width = pSource->GetWidth(); | |
| 456 int height = pSource->GetHeight(); | |
| 457 int rowBytes = pSource->GetPitch(); | |
| 458 switch (pSource->GetBPP()) { | |
| 459 case 1: { | |
| 460 dstStorage.reset(new uint8_t[(int64_t) width * height]); | |
|
Tom Sepez
2016/03/11 17:38:45
Unfortunately, it's almost impossible to get this
caryclark
2016/03/13 01:02:38
Done.
| |
| 461 uint8_t* dst8Pixels = dstStorage.get(); | |
| 462 for (int y = 0; y < height; ++y) { | |
| 463 const uint8_t* srcRow = buffer + y * rowBytes; | |
| 464 uint8_t* dstRow = dst8Pixels + y * width; | |
| 465 for (int x = 0; x < width; ++x) | |
| 466 dstRow[x] = srcRow[x >> 3] & (1 << (~x & 0x07)) ? 0xFF : 0x00; | |
| 467 } | |
| 468 buffer = const_cast<const uint8_t*>(dstStorage.get()); | |
| 469 rowBytes = width; | |
| 470 colorType = SkColorType::kGray_8_SkColorType; | |
| 471 } break; | |
| 472 case 24: { | |
| 473 dstStorage.reset(new uint8_t[(int64_t) width * height * sizeof(uint32_t)]) ; | |
| 474 uint32_t* dst32Pixels = (uint32_t*)dstStorage.get(); | |
| 475 for (int y = 0; y < height; ++y) { | |
| 476 const uint8_t* srcRow = buffer + y * rowBytes; | |
| 477 uint32_t* dstRow = dst32Pixels + y * width; | |
| 478 for (int x = 0; x < width; ++x) | |
| 479 dstRow[x] = SkPackARGB32(0xFF, srcRow[x * 3 + 2], srcRow[x * 3 + 1], | |
| 480 srcRow[x * 3 + 0]); | |
| 481 } | |
| 482 buffer = const_cast<const uint8_t*>(dstStorage.get()); | |
| 483 rowBytes = width * sizeof(uint32_t); | |
| 484 colorType = SkColorType::kN32_SkColorType; | |
| 485 } break; | |
| 486 case 32: | |
| 487 colorType = SkColorType::kN32_SkColorType; | |
| 488 break; | |
| 489 default: | |
| 490 colorType = SkColorType::kUnknown_SkColorType; | |
| 491 } | |
| 492 SkImageInfo imageInfo = | |
| 493 SkImageInfo::Make(width, height, colorType, kOpaque_SkAlphaType); | |
| 494 SkBitmap skBitmap; | |
| 495 skBitmap.installPixels(imageInfo, (void*)buffer, rowBytes, | |
| 496 nullptr, /* TODO(caryclark) : set color table */ | |
| 497 nullptr, nullptr); | |
| 498 m_pCanvas->save(); | |
| 499 bool landscape = !pMatrix->a; | |
| 500 if (landscape) | |
| 501 m_pCanvas->translate(m_pCanvas->imageInfo().width(), 0); | |
| 502 else | |
| 503 m_pCanvas->translate(pMatrix->e, pMatrix->f + pMatrix->d); | |
| 504 | |
| 505 SkMatrix skMatrix = SkMatrix::MakeScale(1.f / width, 1.f / height); | |
| 506 m_pCanvas->concat(skMatrix); | |
| 507 const CFX_Matrix& m = *pMatrix; | |
| 508 // note that PDF's y-axis goes up; Skia's y-axis goes down | |
| 509 if (landscape) | |
| 510 skMatrix.setAll(-m.a, -m.b, m.e, m.c, m.d, m.f, 0, 0, 1); | |
| 511 else | |
| 512 skMatrix.setAll(m.a, m.b, 0, -m.c, -m.d, 0, 0, 0, 1); | |
| 513 m_pCanvas->concat(skMatrix); | |
| 514 SkPaint paint; | |
| 515 paint.setAntiAlias(true); | |
| 516 paint.setFilterQuality(kLow_SkFilterQuality); | |
| 517 m_pCanvas->drawBitmap(skBitmap, 0, 0, &paint); | |
| 518 m_pCanvas->restore(); | |
| 519 return TRUE; | |
| 362 } | 520 } |
| 363 | 521 |
| 364 FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) { | 522 FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) { |
| 365 return m_pAggDriver->ContinueDIBits(pHandle, pPause); | 523 return m_pAggDriver && m_pAggDriver->ContinueDIBits(pHandle, pPause); |
| 366 } | 524 } |
| 367 | 525 |
| 368 void CFX_SkiaDeviceDriver::CancelDIBits(void* pHandle) { | 526 void CFX_SkiaDeviceDriver::CancelDIBits(void* pHandle) { |
| 369 m_pAggDriver->CancelDIBits(pHandle); | 527 if (m_pAggDriver) |
| 528 m_pAggDriver->CancelDIBits(pHandle); | |
| 370 } | 529 } |
| 371 | 530 |
| 372 CFX_SkiaDevice::CFX_SkiaDevice() { | 531 CFX_SkiaDevice::CFX_SkiaDevice() { |
| 373 m_bOwnedBitmap = FALSE; | 532 m_bOwnedBitmap = FALSE; |
| 374 } | 533 } |
| 375 | 534 |
| 535 SkPictureRecorder* CFX_SkiaDevice::CreateRecorder(int size_x, int size_y) { | |
| 536 CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y); | |
| 537 SetDeviceDriver(skDriver); | |
| 538 return skDriver->GetRecorder(); | |
| 539 } | |
| 540 | |
| 376 FX_BOOL CFX_SkiaDevice::Attach(CFX_DIBitmap* pBitmap, | 541 FX_BOOL CFX_SkiaDevice::Attach(CFX_DIBitmap* pBitmap, |
| 377 int dither_bits, | 542 int dither_bits, |
| 378 FX_BOOL bRgbByteOrder, | 543 FX_BOOL bRgbByteOrder, |
| 379 CFX_DIBitmap* pOriDevice, | 544 CFX_DIBitmap* pOriDevice, |
| 380 FX_BOOL bGroupKnockout) { | 545 FX_BOOL bGroupKnockout) { |
| 381 if (!pBitmap) | 546 if (!pBitmap) |
| 382 return FALSE; | 547 return FALSE; |
| 383 SetBitmap(pBitmap); | 548 SetBitmap(pBitmap); |
| 384 CFX_SkiaDeviceDriver* pDriver = new CFX_SkiaDeviceDriver( | 549 SetDeviceDriver(new CFX_SkiaDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, |
| 385 pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout); | 550 pOriDevice, bGroupKnockout)); |
| 386 SetDeviceDriver(pDriver); | |
| 387 return TRUE; | 551 return TRUE; |
| 388 } | 552 } |
| 389 | 553 |
| 554 FX_BOOL CFX_SkiaDevice::AttachRecorder(SkPictureRecorder* recorder) { | |
| 555 if (!recorder) | |
| 556 return FALSE; | |
| 557 SetDeviceDriver(new CFX_SkiaDeviceDriver(recorder)); | |
| 558 return TRUE; | |
| 559 } | |
| 560 | |
| 390 FX_BOOL CFX_SkiaDevice::Create(int width, | 561 FX_BOOL CFX_SkiaDevice::Create(int width, |
| 391 int height, | 562 int height, |
| 392 FXDIB_Format format, | 563 FXDIB_Format format, |
| 393 int dither_bits, | 564 int dither_bits, |
| 394 CFX_DIBitmap* pOriDevice) { | 565 CFX_DIBitmap* pOriDevice) { |
| 395 m_bOwnedBitmap = TRUE; | 566 m_bOwnedBitmap = TRUE; |
| 396 CFX_DIBitmap* pBitmap = new CFX_DIBitmap; | 567 CFX_DIBitmap* pBitmap = new CFX_DIBitmap; |
| 397 if (!pBitmap->Create(width, height, format)) { | 568 if (!pBitmap->Create(width, height, format)) { |
| 398 delete pBitmap; | 569 delete pBitmap; |
| 399 return FALSE; | 570 return FALSE; |
| 400 } | 571 } |
| 401 SetBitmap(pBitmap); | 572 SetBitmap(pBitmap); |
| 402 CFX_SkiaDeviceDriver* pDriver = | 573 CFX_SkiaDeviceDriver* pDriver = |
| 403 new CFX_SkiaDeviceDriver(pBitmap, dither_bits, FALSE, pOriDevice, FALSE); | 574 new CFX_SkiaDeviceDriver(pBitmap, dither_bits, FALSE, pOriDevice, FALSE); |
| 404 SetDeviceDriver(pDriver); | 575 SetDeviceDriver(pDriver); |
| 405 return TRUE; | 576 return TRUE; |
| 406 } | 577 } |
| 407 | 578 |
| 408 CFX_SkiaDevice::~CFX_SkiaDevice() { | 579 CFX_SkiaDevice::~CFX_SkiaDevice() { |
| 409 if (m_bOwnedBitmap && GetBitmap()) | 580 if (m_bOwnedBitmap && GetBitmap()) |
| 410 delete GetBitmap(); | 581 delete GetBitmap(); |
| 411 } | 582 } |
| 412 | 583 |
| 413 #if 0 | |
| 414 #include <stdarg.h> | |
| 415 #include <stdio.h> | |
| 416 | |
| 417 void SkDebugf(const char format[], ...) { | |
| 418 va_list args; | |
| 419 va_start(args, format); | |
| 420 vfprintf(stderr, format, args); | |
| 421 va_end(args); | |
| 422 } | |
| 423 | |
| 424 #endif | 584 #endif |
| 425 | |
| 426 #endif | |
| OLD | NEW |