Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkPDFDevice.h" | 8 #include "SkPDFDevice.h" |
| 9 | 9 |
| 10 #include "SkAnnotation.h" | 10 #include "SkAnnotation.h" |
| (...skipping 2010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2021 SkAutoTUnref<SkPDFFont> newFont(SkPDFFont::GetFontResource(typeface, glyphID )); | 2021 SkAutoTUnref<SkPDFFont> newFont(SkPDFFont::GetFontResource(typeface, glyphID )); |
| 2022 int resourceIndex = fFontResources.find(newFont.get()); | 2022 int resourceIndex = fFontResources.find(newFont.get()); |
| 2023 if (resourceIndex < 0) { | 2023 if (resourceIndex < 0) { |
| 2024 resourceIndex = fFontResources.count(); | 2024 resourceIndex = fFontResources.count(); |
| 2025 fFontResources.push(newFont.get()); | 2025 fFontResources.push(newFont.get()); |
| 2026 newFont.get()->ref(); | 2026 newFont.get()->ref(); |
| 2027 } | 2027 } |
| 2028 return resourceIndex; | 2028 return resourceIndex; |
| 2029 } | 2029 } |
| 2030 | 2030 |
| 2031 void SkPDFDevice::internalDrawBitmap(const SkMatrix& matrix, | 2031 static void setup_transparent_bitmap(SkBitmap* bitmap, int width, int height) { |
|
vandebo (ex-Chrome)
2013/10/16 16:46:41
nit: it seems unlikely that this will get reused.
edisonn
2013/10/16 18:28:52
Done.
| |
| 2032 bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); | |
| 2033 bitmap->allocPixels(); | |
| 2034 bitmap->eraseColor(SK_ColorTRANSPARENT); | |
| 2035 } | |
| 2036 | |
| 2037 void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix, | |
| 2032 const SkClipStack* clipStack, | 2038 const SkClipStack* clipStack, |
| 2033 const SkRegion& clipRegion, | 2039 const SkRegion& origClipRegion, |
| 2034 const SkBitmap& bitmap, | 2040 const SkBitmap& origBitmap, |
| 2035 const SkIRect* srcRect, | 2041 const SkIRect* srcRect, |
| 2036 const SkPaint& paint) { | 2042 const SkPaint& paint) { |
| 2037 // TODO(edisonn): Perspective matrix support implemented here | 2043 SkMatrix matrix = origMatrix; |
| 2044 SkRegion perspectiveBounds; | |
| 2045 const SkRegion* clipRegion = &origClipRegion; | |
| 2046 SkBitmap subsetBitmap; | |
| 2047 SkBitmap perspectiveBitmap; | |
| 2048 const SkBitmap* bitmap = &origBitmap; | |
| 2049 | |
| 2050 // Raster the bitmap using perspective in a new bitmap. | |
|
vandebo (ex-Chrome)
2013/10/16 16:46:41
nit: Raster -> Rasterize/Render
edisonn
2013/10/16 18:28:52
Done.
| |
| 2051 if (origMatrix.hasPerspective()) { | |
| 2052 // TODO(edisonn): testability - add a flag to force this codepath. | |
|
vandebo (ex-Chrome)
2013/10/16 16:46:41
nit: Remove - you could pass a matrix with perspec
edisonn
2013/10/16 18:28:52
Done.
| |
| 2053 if (srcRect) { | |
| 2054 if (!origBitmap.extractSubset(&subsetBitmap, *srcRect)) { | |
| 2055 return; | |
| 2056 } | |
| 2057 } else { | |
| 2058 subsetBitmap = origBitmap; | |
|
vandebo (ex-Chrome)
2013/10/16 16:46:41
nit: this makes a copy. You could move "SkBitmap
edisonn
2013/10/16 18:28:52
Done.
| |
| 2059 } | |
| 2060 srcRect = NULL; | |
| 2061 | |
| 2062 // Transform the bitmap in the new space. | |
| 2063 SkPath perspectiveOutline; | |
| 2064 perspectiveOutline.addRect(SkRect::MakeWH(SkIntToScalar(subsetBitmap.wid th()), | |
| 2065 SkIntToScalar(subsetBitmap.hei ght()))); | |
| 2066 perspectiveOutline.transform(origMatrix); | |
| 2067 | |
| 2068 // Retrieve the bounds of the new shape. | |
| 2069 SkRect bounds = perspectiveOutline.getBounds(); | |
| 2070 | |
| 2071 // TODO(edisonn): add DPI settings. Currently 1 pixel/point, which does not look great, | |
| 2072 // but it is not producing large PDFs. | |
| 2073 | |
| 2074 // TODO(edisonn): A better approach would be to use a bitmap shader (in clamp mode) and | |
| 2075 // draw a rect over the entire bounding box. Then intersect perspectiveO utline to the clip. | |
| 2076 // That will avoid introducing alpha to the image while still giving goo d behavior at the | |
| 2077 // edge of the image. Avoiding alpha will reduce the pdf size and gener ation CPU time some. | |
| 2078 | |
| 2079 // Create transparent bitmap. | |
|
vandebo (ex-Chrome)
2013/10/16 16:46:41
nit: comment is unnecessary
edisonn
2013/10/16 18:28:52
Done.
| |
| 2080 setup_transparent_bitmap(&perspectiveBitmap, bounds.width(), bounds.heig ht()); | |
| 2081 | |
| 2082 SkBitmapDevice device(perspectiveBitmap); | |
| 2083 SkCanvas canvas(&device); | |
| 2084 | |
| 2085 SkScalar deltaX = bounds.left(); | |
| 2086 SkScalar deltaY = bounds.top(); | |
| 2087 | |
| 2088 SkMatrix offsetMatrix = origMatrix; | |
| 2089 offsetMatrix.postTranslate(-deltaX, -deltaY); | |
| 2090 | |
| 2091 // Translate the draw in the new canvas, so we perfectly fit the shape i n the bitmap. | |
| 2092 canvas.setMatrix(offsetMatrix); | |
| 2093 | |
| 2094 canvas.drawBitmap(subsetBitmap, SkIntToScalar(0), SkIntToScalar(0)); | |
| 2095 | |
| 2096 // Make sure the final bits are in the bitmap. | |
| 2097 canvas.flush(); | |
| 2098 | |
| 2099 // In the new space, we use the identity matrix translated. | |
| 2100 matrix.setTranslate(deltaX, deltaY); | |
| 2101 perspectiveBounds.setRect(SkIRect::MakeXYWH(SkScalarToFixed(bounds.x()), | |
| 2102 SkScalarToFixed(bounds.y()), | |
| 2103 SkScalarToFixed(bounds.width ()), | |
| 2104 SkScalarToFixed(bounds.heigh t()))); | |
| 2105 clipRegion = &perspectiveBounds; | |
| 2106 srcRect = NULL; | |
| 2107 bitmap = &perspectiveBitmap; | |
| 2108 } | |
| 2109 | |
| 2038 SkMatrix scaled; | 2110 SkMatrix scaled; |
| 2039 // Adjust for origin flip. | 2111 // Adjust for origin flip. |
| 2040 scaled.setScale(SK_Scalar1, -SK_Scalar1); | 2112 scaled.setScale(SK_Scalar1, -SK_Scalar1); |
| 2041 scaled.postTranslate(0, SK_Scalar1); | 2113 scaled.postTranslate(0, SK_Scalar1); |
| 2042 // Scale the image up from 1x1 to WxH. | 2114 // Scale the image up from 1x1 to WxH. |
| 2043 SkIRect subset = SkIRect::MakeWH(bitmap.width(), bitmap.height()); | 2115 SkIRect subset = SkIRect::MakeWH(bitmap->width(), bitmap->height()); |
| 2044 scaled.postScale(SkIntToScalar(subset.width()), | 2116 scaled.postScale(SkIntToScalar(subset.width()), |
| 2045 SkIntToScalar(subset.height())); | 2117 SkIntToScalar(subset.height())); |
| 2046 scaled.postConcat(matrix); | 2118 scaled.postConcat(matrix); |
| 2047 ScopedContentEntry content(this, clipStack, clipRegion, scaled, paint); | 2119 ScopedContentEntry content(this, clipStack, *clipRegion, scaled, paint); |
| 2048 if (!content.entry()) { | 2120 if (!content.entry()) { |
| 2049 return; | 2121 return; |
| 2050 } | 2122 } |
| 2051 | 2123 |
| 2052 if (srcRect && !subset.intersect(*srcRect)) { | 2124 if (srcRect && !subset.intersect(*srcRect)) { |
| 2053 return; | 2125 return; |
| 2054 } | 2126 } |
| 2055 | 2127 |
| 2056 SkPDFImage* image = SkPDFImage::CreateImage(bitmap, subset, fEncoder); | 2128 SkPDFImage* image = SkPDFImage::CreateImage(*bitmap, subset, fEncoder); |
| 2057 if (!image) { | 2129 if (!image) { |
| 2058 return; | 2130 return; |
| 2059 } | 2131 } |
| 2060 | 2132 |
| 2061 fXObjectResources.push(image); // Transfer reference. | 2133 fXObjectResources.push(image); // Transfer reference. |
| 2062 SkPDFUtils::DrawFormXObject(fXObjectResources.count() - 1, | 2134 SkPDFUtils::DrawFormXObject(fXObjectResources.count() - 1, |
| 2063 &content.entry()->fContent); | 2135 &content.entry()->fContent); |
| 2064 } | 2136 } |
| 2065 | 2137 |
| 2066 bool SkPDFDevice::onReadPixels(const SkBitmap& bitmap, int x, int y, | 2138 bool SkPDFDevice::onReadPixels(const SkBitmap& bitmap, int x, int y, |
| 2067 SkCanvas::Config8888) { | 2139 SkCanvas::Config8888) { |
| 2068 return false; | 2140 return false; |
| 2069 } | 2141 } |
| 2070 | 2142 |
| 2071 bool SkPDFDevice::allowImageFilter(SkImageFilter*) { | 2143 bool SkPDFDevice::allowImageFilter(SkImageFilter*) { |
| 2072 return false; | 2144 return false; |
| 2073 } | 2145 } |
| OLD | NEW |