| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "SkCanvas.h" | 8 #include "SkCanvas.h" |
| 9 #include "SkDevice.h" | 9 #include "SkDevice.h" |
| 10 #include "SkForceLinking.h" | 10 #include "SkForceLinking.h" |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 SkPoint to[4] = {SkPoint::Make(z, one), SkPoint::Make(one, one), SkPoint::Ma
ke(one, z), SkPoint::Make(z, z)}; | 608 SkPoint to[4] = {SkPoint::Make(z, one), SkPoint::Make(one, one), SkPoint::Ma
ke(one, z), SkPoint::Make(z, z)}; |
| 609 SkMatrix flip; | 609 SkMatrix flip; |
| 610 SkAssertResult(flip.setPolyToPoly(from, to, 4)); | 610 SkAssertResult(flip.setPolyToPoly(from, to, 4)); |
| 611 SkMatrix solveImageFlip = pdfContext->fGraphicsState.fCTM; | 611 SkMatrix solveImageFlip = pdfContext->fGraphicsState.fCTM; |
| 612 solveImageFlip.preConcat(flip); | 612 solveImageFlip.preConcat(flip); |
| 613 canvas->setMatrix(solveImageFlip); | 613 canvas->setMatrix(solveImageFlip); |
| 614 #endif | 614 #endif |
| 615 | 615 |
| 616 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); | 616 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); |
| 617 | 617 |
| 618 // TODO(edisonn): soft mask type? alpha/luminosity. |
| 618 if (sMask.empty()) { | 619 if (sMask.empty()) { |
| 619 canvas->drawBitmapRect(image, dst, NULL); | 620 canvas->drawBitmapRect(image, dst, NULL); |
| 620 } else { | 621 } else { |
| 621 canvas->saveLayer(&dst, NULL); | 622 canvas->saveLayer(&dst, NULL); |
| 622 canvas->drawBitmapRect(image, dst, NULL); | 623 canvas->drawBitmapRect(image, dst, NULL); |
| 623 SkPaint xfer; | 624 SkPaint xfer; |
| 624 pdfContext->fGraphicsState.applyGraphicsState(&xfer, false); | 625 pdfContext->fGraphicsState.applyGraphicsState(&xfer, false); |
| 626 // TODO(edisonn): is the blend mode specified already implicitly/explici
tly in pdf? |
| 625 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode | 627 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode |
| 626 canvas->drawBitmapRect(sMask, dst, &xfer); | 628 canvas->drawBitmapRect(sMask, dst, &xfer); |
| 627 canvas->restore(); | 629 canvas->restore(); |
| 628 } | 630 } |
| 629 | 631 |
| 630 canvas->restore(); | 632 canvas->restore(); |
| 631 | 633 |
| 632 return kPartial_PdfResult; | 634 return kPartial_PdfResult; |
| 633 } | 635 } |
| 634 | 636 |
| 635 | |
| 636 | |
| 637 | |
| 638 static PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfT
ype1FormDictionary* skobj) { | 637 static PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfT
ype1FormDictionary* skobj) { |
| 639 if (!skobj || !skobj->hasStream()) { | 638 if (!skobj || !skobj->hasStream()) { |
| 640 return kIgnoreError_PdfResult; | 639 return kIgnoreError_PdfResult; |
| 641 } | 640 } |
| 642 | 641 |
| 643 PdfOp_q(pdfContext, canvas, NULL); | 642 PdfOp_q(pdfContext, canvas, NULL); |
| 643 |
| 644 |
| 645 |
| 644 canvas->save(); | 646 canvas->save(); |
| 645 | 647 |
| 646 | 648 |
| 647 if (skobj->Resources(pdfContext->fPdfDoc)) { | 649 if (skobj->Resources(pdfContext->fPdfDoc)) { |
| 648 pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPd
fDoc); | 650 pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPd
fDoc); |
| 649 } | 651 } |
| 650 | 652 |
| 651 SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Current matrix"); | 653 SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Current matrix"); |
| 652 | 654 |
| 653 if (skobj->has_Matrix()) { | 655 if (skobj->has_Matrix()) { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 //space units. Text leading is used only by the T*, ', and " operators. Initial
value: 0. | 836 //space units. Text leading is used only by the T*, ', and " operators. Initial
value: 0. |
| 835 static PdfResult PdfOp_TL(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLoop
er** looper) { | 837 static PdfResult PdfOp_TL(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLoop
er** looper) { |
| 836 double ty = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fOb
jectStack.pop(); | 838 double ty = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fOb
jectStack.pop(); |
| 837 | 839 |
| 838 pdfContext->fGraphicsState.fTextLeading = ty; | 840 pdfContext->fGraphicsState.fTextLeading = ty; |
| 839 | 841 |
| 840 return kOK_PdfResult; | 842 return kOK_PdfResult; |
| 841 } | 843 } |
| 842 | 844 |
| 843 static PdfResult PdfOp_Td(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLoop
er** looper) { | 845 static PdfResult PdfOp_Td(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLoop
er** looper) { |
| 846 #ifdef PDF_TRACE |
| 847 printf("stack size = %i\n", (int)pdfContext->fObjectStack.size()); |
| 848 #endif |
| 844 double ty = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObje
ctStack.pop(); | 849 double ty = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObje
ctStack.pop(); |
| 850 SkPdfObject* obj = pdfContext->fObjectStack.top(); |
| 851 obj = obj; |
| 845 double tx = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObje
ctStack.pop(); | 852 double tx = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObje
ctStack.pop(); |
| 846 | 853 |
| 847 double array[6] = {1, 0, 0, 1, tx, ty}; | 854 double array[6] = {1, 0, 0, 1, tx, ty}; |
| 848 SkMatrix matrix = SkMatrixFromPdfMatrix(array); | 855 SkMatrix matrix = SkMatrixFromPdfMatrix(array); |
| 849 | 856 |
| 850 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 857 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
| 851 pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); | 858 pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); |
| 852 | 859 |
| 853 return kPartial_PdfResult; | 860 return kPartial_PdfResult; |
| 854 } | 861 } |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1658 | 1665 |
| 1659 pdfContext->fGraphicsState.fBlendModesLength = cnt; | 1666 pdfContext->fGraphicsState.fBlendModesLength = cnt; |
| 1660 for (int i = 0; i < cnt; i++) { | 1667 for (int i = 0; i < cnt; i++) { |
| 1661 pdfContext->fGraphicsState.fBlendModes[i] = modes[i]; | 1668 pdfContext->fGraphicsState.fBlendModes[i] = modes[i]; |
| 1662 } | 1669 } |
| 1663 } | 1670 } |
| 1664 | 1671 |
| 1665 void skpdfGraphicsStateApplySMask_dict(PdfContext* pdfContext, SkPdfDictionary*
sMask) { | 1672 void skpdfGraphicsStateApplySMask_dict(PdfContext* pdfContext, SkPdfDictionary*
sMask) { |
| 1666 // TODO(edisonn): verify input | 1673 // TODO(edisonn): verify input |
| 1667 if (pdfContext->fPdfDoc->mapper()->mapSoftMaskDictionary(sMask)) { | 1674 if (pdfContext->fPdfDoc->mapper()->mapSoftMaskDictionary(sMask)) { |
| 1668 //SkPdfSoftMaskDictionary* smd = (SkPdfSoftMaskDictionary*)sMask; | 1675 pdfContext->fGraphicsState.fSoftMaskDictionary = (SkPdfSoftMaskDictionar
y*)sMask; |
| 1669 // TODO(edisonn): load soft mask | |
| 1670 } else if (pdfContext->fPdfDoc->mapper()->mapSoftMaskImageDictionary(sMask))
{ | 1676 } else if (pdfContext->fPdfDoc->mapper()->mapSoftMaskImageDictionary(sMask))
{ |
| 1671 SkPdfSoftMaskImageDictionary* smid = (SkPdfSoftMaskImageDictionary*)sMas
k; | 1677 SkPdfSoftMaskImageDictionary* smid = (SkPdfSoftMaskImageDictionary*)sMas
k; |
| 1672 pdfContext->fGraphicsState.fSMask = getImageFromObject(pdfContext, smid,
true); | 1678 pdfContext->fGraphicsState.fSMask = getImageFromObject(pdfContext, smid,
true); |
| 1673 } else { | 1679 } else { |
| 1674 // TODO (edisonn): report error/warning | 1680 // TODO (edisonn): report error/warning |
| 1675 } | 1681 } |
| 1676 } | 1682 } |
| 1677 | 1683 |
| 1678 void skpdfGraphicsStateApplySMask_name(PdfContext* pdfContext, const std::string
& sMask) { | 1684 void skpdfGraphicsStateApplySMask_name(PdfContext* pdfContext, const std::string
& sMask) { |
| 1685 if (sMask == "None") { |
| 1686 pdfContext->fGraphicsState.fSoftMaskDictionary = NULL; |
| 1687 pdfContext->fGraphicsState.fSMask = SkBitmap(); |
| 1688 return; |
| 1689 } |
| 1690 |
| 1679 //Next, get the ExtGState Dictionary from the Resource Dictionary: | 1691 //Next, get the ExtGState Dictionary from the Resource Dictionary: |
| 1680 SkPdfDictionary* extGStateDictionary = pdfContext->fGraphicsState.fResources
->ExtGState(pdfContext->fPdfDoc); | 1692 SkPdfDictionary* extGStateDictionary = pdfContext->fGraphicsState.fResources
->ExtGState(pdfContext->fPdfDoc); |
| 1681 | 1693 |
| 1682 if (extGStateDictionary == NULL) { | 1694 if (extGStateDictionary == NULL) { |
| 1683 #ifdef PDF_TRACE | 1695 #ifdef PDF_TRACE |
| 1684 printf("ExtGState is NULL!\n"); | 1696 printf("ExtGState is NULL!\n"); |
| 1685 #endif | 1697 #endif |
| 1686 // TODO (edisonn): report error/warning | 1698 // TODO (edisonn): report error/warning |
| 1687 return; | 1699 return; |
| 1688 } | 1700 } |
| 1689 | 1701 |
| 1690 SkPdfObject* obj = pdfContext->fPdfDoc->resolveReference(extGStateDictionary
->get(sMask.c_str())); | 1702 SkPdfObject* obj = pdfContext->fPdfDoc->resolveReference(extGStateDictionary
->get(sMask.c_str())); |
| 1691 if (!obj || !obj->isDictionary()) { | 1703 if (!obj || !obj->isDictionary()) { |
| 1692 // TODO (edisonn): report error/warning | 1704 // TODO (edisonn): report error/warning |
| 1693 return; | 1705 return; |
| 1694 } | 1706 } |
| 1707 |
| 1708 pdfContext->fGraphicsState.fSoftMaskDictionary = NULL; |
| 1709 pdfContext->fGraphicsState.fSMask = SkBitmap(); |
| 1710 |
| 1695 skpdfGraphicsStateApplySMask_dict(pdfContext, obj->asDictionary()); | 1711 skpdfGraphicsStateApplySMask_dict(pdfContext, obj->asDictionary()); |
| 1696 } | 1712 } |
| 1697 | 1713 |
| 1698 void skpdfGraphicsStateApplyAIS(PdfContext* pdfContext, bool alphaSource) { | 1714 void skpdfGraphicsStateApplyAIS(PdfContext* pdfContext, bool alphaSource) { |
| 1699 pdfContext->fGraphicsState.fAlphaSource = alphaSource; | 1715 pdfContext->fGraphicsState.fAlphaSource = alphaSource; |
| 1700 } | 1716 } |
| 1701 | 1717 |
| 1702 | 1718 |
| 1703 //dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictN
ame is | 1719 //dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictN
ame is |
| 1704 //the name of a graphics state parameter dictionary in the ExtGState subdictiona
ry of the current resource dictionary (see the next section). | 1720 //the name of a graphics state parameter dictionary in the ExtGState subdictiona
ry of the current resource dictionary (see the next section). |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2044 SkTDict<int>::Iter iter(gRenderStats[i]); | 2060 SkTDict<int>::Iter iter(gRenderStats[i]); |
| 2045 const char* key; | 2061 const char* key; |
| 2046 int value = 0; | 2062 int value = 0; |
| 2047 while ((key = iter.next(&value)) != NULL) { | 2063 while ((key = iter.next(&value)) != NULL) { |
| 2048 printf("%s: %s -> count %i\n", gRenderStatsNames[i], key, value); | 2064 printf("%s: %s -> count %i\n", gRenderStatsNames[i], key, value); |
| 2049 } | 2065 } |
| 2050 } | 2066 } |
| 2051 } | 2067 } |
| 2052 | 2068 |
| 2053 PdfResult PdfMainLooper::consumeToken(PdfToken& token) { | 2069 PdfResult PdfMainLooper::consumeToken(PdfToken& token) { |
| 2054 char keyword[256]; | |
| 2055 | |
| 2056 if (token.fType == kKeyword_TokenType && token.fKeywordLength < 256) | 2070 if (token.fType == kKeyword_TokenType && token.fKeywordLength < 256) |
| 2057 { | 2071 { |
| 2058 strncpy(keyword, token.fKeyword, token.fKeywordLength); | |
| 2059 keyword[token.fKeywordLength] = '\0'; | |
| 2060 // TODO(edisonn): log trace flag (verbose, error, info, warning, ...) | 2072 // TODO(edisonn): log trace flag (verbose, error, info, warning, ...) |
| 2061 PdfOperatorRenderer pdfOperatorRenderer = NULL; | 2073 PdfOperatorRenderer pdfOperatorRenderer = NULL; |
| 2062 if (gPdfOps.find(keyword, &pdfOperatorRenderer) && pdfOperatorRenderer)
{ | 2074 if (gPdfOps.find(token.fKeyword, token.fKeywordLength, &pdfOperatorRende
rer) && pdfOperatorRenderer) { |
| 2063 // caller, main work is done by pdfOperatorRenderer(...) | 2075 // caller, main work is done by pdfOperatorRenderer(...) |
| 2064 PdfTokenLooper* childLooper = NULL; | 2076 PdfTokenLooper* childLooper = NULL; |
| 2065 PdfResult result = pdfOperatorRenderer(fPdfContext, fCanvas, &childL
ooper); | 2077 PdfResult result = pdfOperatorRenderer(fPdfContext, fCanvas, &childL
ooper); |
| 2066 | 2078 |
| 2067 int cnt = 0; | 2079 int cnt = 0; |
| 2068 gRenderStats[result].find(keyword, &cnt); | 2080 gRenderStats[result].find(token.fKeyword, token.fKeywordLength, &cnt
); |
| 2069 gRenderStats[result].set(keyword, cnt + 1); | 2081 gRenderStats[result].set(token.fKeyword, token.fKeywordLength, cnt +
1); |
| 2070 | 2082 |
| 2071 if (childLooper) { | 2083 if (childLooper) { |
| 2072 childLooper->setUp(this); | 2084 childLooper->setUp(this); |
| 2073 childLooper->loop(); | 2085 childLooper->loop(); |
| 2074 delete childLooper; | 2086 delete childLooper; |
| 2075 } | 2087 } |
| 2076 } else { | 2088 } else { |
| 2077 int cnt = 0; | 2089 int cnt = 0; |
| 2078 gRenderStats[kUnsupported_PdfResult].find(keyword, &cnt); | 2090 gRenderStats[kUnsupported_PdfResult].find(token.fKeyword, token.fKey
wordLength, &cnt); |
| 2079 gRenderStats[kUnsupported_PdfResult].set(keyword, cnt + 1); | 2091 gRenderStats[kUnsupported_PdfResult].set(token.fKeyword, token.fKeyw
ordLength, cnt + 1); |
| 2080 } | 2092 } |
| 2081 } | 2093 } |
| 2082 else if (token.fType == kObject_TokenType) | 2094 else if (token.fType == kObject_TokenType) |
| 2083 { | 2095 { |
| 2084 fPdfContext->fObjectStack.push( token.fObject ); | 2096 fPdfContext->fObjectStack.push( token.fObject ); |
| 2085 } | 2097 } |
| 2086 else { | 2098 else { |
| 2087 // TODO(edisonn): deine or use assert not reached | 2099 // TODO(edisonn): deine or use assert not reached |
| 2088 return kIgnoreError_PdfResult; | 2100 return kIgnoreError_PdfResult; |
| 2089 } | 2101 } |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2306 | 2318 |
| 2307 rect = SkRect::MakeWH(width, height); | 2319 rect = SkRect::MakeWH(width, height); |
| 2308 | 2320 |
| 2309 setup_bitmap(output, (int)SkScalarToDouble(width), (int)SkScalarToDouble(hei
ght)); | 2321 setup_bitmap(output, (int)SkScalarToDouble(width), (int)SkScalarToDouble(hei
ght)); |
| 2310 | 2322 |
| 2311 SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (*output))); | 2323 SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (*output))); |
| 2312 SkCanvas canvas(device); | 2324 SkCanvas canvas(device); |
| 2313 | 2325 |
| 2314 return renderer.renderPage(page, &canvas, rect); | 2326 return renderer.renderPage(page, &canvas, rect); |
| 2315 } | 2327 } |
| OLD | NEW |