sk_sp<SkPDFDict> SkPDFGraphicState::GetSMaskGraphicState( sk_sp<SkPDFObject> sMask, bool invert, SkPDFSMaskMode sMaskMode, SkPDFCanon* canon) { // The practical chances of using the same mask more than once are unlikely // enough that it's not worth canonicalizing. auto sMaskDict = sk_make_sp<SkPDFDict>("Mask"); if (sMaskMode == kAlpha_SMaskMode) { sMaskDict->insertName("S", "Alpha"); } else if (sMaskMode == kLuminosity_SMaskMode) { sMaskDict->insertName("S", "Luminosity"); } sMaskDict->insertObjRef("G", std::move(sMask)); if (invert) { // Instead of calling SkPDFGraphicState::MakeInvertFunction, // let the canon deduplicate this object. sk_sp<SkPDFStream>& invertFunction = canon->fInvertFunction; if (!invertFunction) { invertFunction = make_invert_function(); } sMaskDict->insertObjRef("TR", invertFunction); } auto result = sk_make_sp<SkPDFDict>("ExtGState"); result->insertObject("SMask", std::move(sMaskDict)); return result; }
sk_sp<SkPDFObject> SkPDFMakeFormXObject(std::unique_ptr<SkStreamAsset> content, sk_sp<SkPDFArray> mediaBox, sk_sp<SkPDFDict> resourceDict, const SkMatrix& inverseTransform, const char* colorSpace) { auto form = sk_make_sp<SkPDFStream>(std::move(content)); form->dict()->insertName("Type", "XObject"); form->dict()->insertName("Subtype", "Form"); if (!inverseTransform.isIdentity()) { sk_sp<SkPDFObject> mat(SkPDFUtils::MatrixToArray(inverseTransform)); form->dict()->insertObject("Matrix", std::move(mat)); } form->dict()->insertObject("Resources", std::move(resourceDict)); form->dict()->insertObject("BBox", std::move(mediaBox)); // Right now FormXObject is only used for saveLayer, which implies // isolated blending. Do this conditionally if that changes. // TODO(halcanary): Is this comment obsolete, since we use it for // alpha masks? auto group = sk_make_sp<SkPDFDict>("Group"); group->insertName("S", "Transparency"); if (colorSpace != nullptr) { group->insertName("CS", colorSpace); } group->insertBool("I", true); // Isolated. form->dict()->insertObject("Group", std::move(group)); return std::move(form); }
void SkPDFGraphicState::emitObject( SkWStream* stream, const SkPDFObjNumMap& objNumMap, const SkPDFSubstituteMap& substitutes) const { auto dict = sk_make_sp<SkPDFDict>("ExtGState"); dict->insertName("Type", "ExtGState"); SkScalar alpha = SkIntToScalar(fAlpha) / 0xFF; dict->insertScalar("CA", alpha); dict->insertScalar("ca", alpha); SkPaint::Cap strokeCap = (SkPaint::Cap)fStrokeCap; SkPaint::Join strokeJoin = (SkPaint::Join)fStrokeJoin; SkXfermode::Mode xferMode = (SkXfermode::Mode)fMode; static_assert(SkPaint::kButt_Cap == 0, "paint_cap_mismatch"); static_assert(SkPaint::kRound_Cap == 1, "paint_cap_mismatch"); static_assert(SkPaint::kSquare_Cap == 2, "paint_cap_mismatch"); static_assert(SkPaint::kCapCount == 3, "paint_cap_mismatch"); SkASSERT(strokeCap >= 0 && strokeCap <= 2); dict->insertInt("LC", strokeCap); static_assert(SkPaint::kMiter_Join == 0, "paint_join_mismatch"); static_assert(SkPaint::kRound_Join == 1, "paint_join_mismatch"); static_assert(SkPaint::kBevel_Join == 2, "paint_join_mismatch"); static_assert(SkPaint::kJoinCount == 3, "paint_join_mismatch"); SkASSERT(strokeJoin >= 0 && strokeJoin <= 2); dict->insertInt("LJ", strokeJoin); dict->insertScalar("LW", fStrokeWidth); dict->insertScalar("ML", fStrokeMiter); dict->insertBool("SA", true); // SA = Auto stroke adjustment. dict->insertName("BM", as_blend_mode(xferMode)); dict->emitObject(stream, objNumMap, substitutes); }
int searchName(char *name) { int valid = -1, count = 0; // valid는 이름이 유효한지 확인, count는 에러메세지가 필요한지 확인 while (valid == -1){ if (count != 0) textColor(12); else textColor(10); gotoxy(4, 14); printf(" ┌───────┐"); gotoxy(16, 15); printf("│ │"); gotoxy(4, 16); printf(" └───────┘ "); textColor(7); gotoxy(4, 15); printf("검색할 이름:"); gotoxy(19, 15); valid = insertName(19, 15, name, 0); if (valid == -1){ case4SearchOptionUI(); textColor(12*16); gotoxy(0, 28); printf(" Warning: 이름은 띄어쓰기 없이 4자이내로 한글만 입력하세요 "); } count++; } gotoxy(0, 16); lineClear(); gotoxy(0, 17); lineClear(); gotoxy(0, 18); lineClear(); gotoxy(0, 26); lineClear(); gotoxy(0, 28); lineClear(); if (valid == 0) return 0; return -1; }
/** * Common initialization code. * Note that bbox is unreferenced here, so calling code does not need worry. */ void SkPDFFormXObject::init(const char* colorSpace, SkPDFDict* resourceDict, SkPDFArray* bbox) { this->insertName("Type", "XObject"); this->insertName("Subtype", "Form"); this->insertObject("Resources", sk_ref_sp(resourceDict)); this->insertObject("BBox", sk_ref_sp(bbox)); // Right now SkPDFFormXObject is only used for saveLayer, which implies // isolated blending. Do this conditionally if that changes. auto group = sk_make_sp<SkPDFDict>("Group"); group->insertName("S", "Transparency"); if (colorSpace != nullptr) { group->insertName("CS", colorSpace); } group->insertBool("I", true); // Isolated. this->insertObject("Group", std::move(group)); }
// populateDict and operator== have to stay in sync with each other. void SkPDFGraphicState::populateDict() { if (!fPopulated) { fPopulated = true; insertName("Type", "ExtGState"); SkRefPtr<SkPDFScalar> alpha = new SkPDFScalar(fPaint.getAlpha() * SkScalarInvert(0xFF)); alpha->unref(); // SkRefPtr and new both took a reference. insert("CA", alpha.get()); insert("ca", alpha.get()); SK_COMPILE_ASSERT(SkPaint::kButt_Cap == 0, paint_cap_mismatch); SK_COMPILE_ASSERT(SkPaint::kRound_Cap == 1, paint_cap_mismatch); SK_COMPILE_ASSERT(SkPaint::kSquare_Cap == 2, paint_cap_mismatch); SK_COMPILE_ASSERT(SkPaint::kCapCount == 3, paint_cap_mismatch); SkASSERT(fPaint.getStrokeCap() >= 0 && fPaint.getStrokeCap() <= 2); insertInt("LC", fPaint.getStrokeCap()); SK_COMPILE_ASSERT(SkPaint::kMiter_Join == 0, paint_join_mismatch); SK_COMPILE_ASSERT(SkPaint::kRound_Join == 1, paint_join_mismatch); SK_COMPILE_ASSERT(SkPaint::kBevel_Join == 2, paint_join_mismatch); SK_COMPILE_ASSERT(SkPaint::kJoinCount == 3, paint_join_mismatch); SkASSERT(fPaint.getStrokeJoin() >= 0 && fPaint.getStrokeJoin() <= 2); insertInt("LJ", fPaint.getStrokeJoin()); insertScalar("LW", fPaint.getStrokeWidth()); insertScalar("ML", fPaint.getStrokeMiter()); insert("SA", new SkPDFBool(true))->unref(); // Auto stroke adjustment. SkXfermode::Mode xfermode = SkXfermode::kSrcOver_Mode; // If asMode fails, default to kSrcOver_Mode. if (fPaint.getXfermode()) fPaint.getXfermode()->asMode(&xfermode); // If we don't support the mode, just use kSrcOver_Mode. if (xfermode < 0 || xfermode > SkXfermode::kLastMode || blend_mode_from_xfermode(xfermode) == NULL) { xfermode = SkXfermode::kSrcOver_Mode; NOT_IMPLEMENTED("unsupported xfermode", false); } insertName("BM", blend_mode_from_xfermode(xfermode)); } }
void insertName() { char name[30]; printf("Insert your first name (Max 30 characters): "); scanf("%s", name); int isValid = validateName(name); if (isValid) printf("Hi %s! Nice to meet you!\n\n", name); else insertName(); }
void CAlgorithmSettingsModel::algorithmChanged(int step) { QJsonObject object = workflow->getStep(step)->GetParameterJson(); loadQJson(object); mRootItem->getChilds()->swap(step, mRootItem->getChilds()->size() - 1); mRootItem->getChilds()->removeLast(); insertName(step); workflow->getStep(step)->getAlgorithm()->setParameters(object); QUrl url; url.setPassword("a" + object.keys().value(0)); emit saveQJson(object, url); }
sk_sp<SkPDFDict> SkPDFGraphicState::GetGraphicStateForPaint(SkPDFCanon* canon, const SkPaint& p) { SkASSERT(canon); if (SkPaint::kFill_Style == p.getStyle()) { SkPDFFillGraphicState fillKey = {p.getAlpha(), pdf_blend_mode(p.getBlendMode())}; auto& fillMap = canon->fFillGSMap; if (sk_sp<SkPDFDict>* statePtr = fillMap.find(fillKey)) { return *statePtr; } auto state = sk_make_sp<SkPDFDict>(); state->reserve(2); state->insertScalar("ca", fillKey.fAlpha / 255.0f); state->insertName("BM", as_pdf_blend_mode_name((SkBlendMode)fillKey.fBlendMode)); fillMap.set(fillKey, state); return state; } else { SkPDFStrokeGraphicState strokeKey = { p.getStrokeWidth(), p.getStrokeMiter(), SkToU8(p.getStrokeCap()), SkToU8(p.getStrokeJoin()), p.getAlpha(), pdf_blend_mode(p.getBlendMode())}; auto& sMap = canon->fStrokeGSMap; if (sk_sp<SkPDFDict>* statePtr = sMap.find(strokeKey)) { return *statePtr; } auto state = sk_make_sp<SkPDFDict>(); state->reserve(8); state->insertScalar("CA", strokeKey.fAlpha / 255.0f); state->insertScalar("ca", strokeKey.fAlpha / 255.0f); state->insertInt("LC", to_stroke_cap(strokeKey.fStrokeCap)); state->insertInt("LJ", to_stroke_join(strokeKey.fStrokeJoin)); state->insertScalar("LW", strokeKey.fStrokeWidth); state->insertScalar("ML", strokeKey.fStrokeMiter); state->insertBool("SA", true); // SA = Auto stroke adjustment. state->insertName("BM", as_pdf_blend_mode_name((SkBlendMode)strokeKey.fBlendMode)); sMap.set(strokeKey, state); return state; } }
int main() { char name[30], dob[11], email[30], phone[11]; printf("Registration Portal:\n\n"); insertName(); // insertDOB(); // insertEmail( // insertPhone(); printf("Registration Successful.\n\n"); return 0; }
SkPDFFormXObject::SkPDFFormXObject(SkPDFDevice* device) { // We don't want to keep around device because we'd have two copies // of content, so reference or copy everything we need (content and // resources). device->getResources(&fResources, false); SkRefPtr<SkStream> content = device->content(); content->unref(); // SkRefPtr and content() both took a reference. setData(content.get()); insertName("Type", "XObject"); insertName("Subtype", "Form"); insert("BBox", device->getMediaBox().get()); insert("Resources", device->getResourceDict()); // We invert the initial transform and apply that to the xobject so that // it doesn't get applied twice. We can't just undo it because it's // embedded in things like shaders and images. if (!device->initialTransform().isIdentity()) { SkMatrix inverse; if (!device->initialTransform().invert(&inverse)) { // The initial transform should be invertible. SkASSERT(false); inverse.reset(); } insert("Matrix", SkPDFUtils::MatrixToArray(inverse))->unref(); } // Right now SkPDFFormXObject is only used for saveLayer, which implies // isolated blending. Do this conditionally if that changes. SkRefPtr<SkPDFDict> group = new SkPDFDict("Group"); group->unref(); // SkRefPtr and new both took a reference. group->insertName("S", "Transparency"); group->insert("I", new SkPDFBool(true))->unref(); // Isolated. insert("Group", group.get()); }
bool SkPDFImage::populate(SkPDFCatalog* catalog) { if (getState() == kUnused_State) { // Initializing image data for the first time. SkDynamicMemoryWStream dctCompressedWStream; if (!skip_compression(catalog) && fEncoder && get_uncompressed_size(fBitmap, fSrcRect) > 1) { SkBitmap subset; // Extract subset if (!fBitmap.extractSubset(&subset, fSrcRect)) { return false; } size_t pixelRefOffset = 0; SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset)); if (data.get() && data->size() < get_uncompressed_size(fBitmap, fSrcRect)) { this->setData(data.get()); insertName("Filter", "DCTDecode"); insertInt("ColorTransform", kNoColorTransform); insertInt("Length", this->dataSize()); setState(kCompressed_State); return true; } } // Fallback method if (!fStreamValid) { SkAutoTUnref<SkStream> stream( extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL)); this->setData(stream); fStreamValid = true; } return INHERITED::populate(catalog); } else if (getState() == kNoCompression_State && !skip_compression(catalog) && (SkFlate::HaveFlate() || fEncoder)) { // Compression has not been requested when the stream was first created, // but the new catalog wants it compressed. if (!getSubstitute()) { SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this)); setSubstitute(substitute); catalog->setSubstitute(this, substitute); } return false; } return true; }
void CAlgorithmSettingsModel::loadSettings(int row, QUrl filename) { if (filename.isEmpty() == true) { return; } emit requestQJson(filename); int j = mRootItem->getChilds()->size() - 1; CQJsonTreeItem* oItem = mRootItem->child(row); CQJsonTreeItem* nItem = mRootItem->child(j); int ois = oItem->childCount(); int nis = nItem->childCount(); if(ois != nis){ CLogController::instance().frameworkMessage("Error: Invalid Load Data"); return; } this->beginResetModel(); mRootItem->getChilds()->swap(row, j); mRootItem->getChilds()->removeAt(j); insertName(row); this->endResetModel(); CLogController::instance().frameworkMessage("File: " + filename.toString() + " loaded"); }
bool SkPDFStream::populate(SkPDFCatalog* catalog) { #ifdef SK_NO_FLATE if (fState == kUnused_State) { fState = kNoCompression_State; insertInt("Length", this->dataSize()); } return true; #else // !SK_NO_FLATE if (fState == kUnused_State) { fState = kNoCompression_State; SkDynamicMemoryWStream compressedData; SkAssertResult( SkFlate::Deflate(fDataStream.get(), &compressedData)); SkAssertResult(fDataStream->rewind()); if (compressedData.getOffset() < this->dataSize()) { SkAutoTDelete<SkStream> compressed( compressedData.detachAsStream()); this->setData(compressed.get()); insertName("Filter", "FlateDecode"); } fState = kCompressed_State; insertInt("Length", this->dataSize()); } else if (fState == kNoCompression_State) { if (!fSubstitute.get()) { fSubstitute.reset(new SkPDFStream(*this)); catalog->setSubstitute(this, fSubstitute.get()); } return false; } return true; #endif // SK_NO_FLATE }
SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) { fState.get()->fImage.lockPixels(); SkMatrix finalMatrix = fState.get()->fCanvasTransform; finalMatrix.preConcat(fState.get()->fShaderTransform); SkRect surfaceBBox; surfaceBBox.set(fState.get()->fBBox); transformBBox(finalMatrix, &surfaceBBox); SkMatrix unflip; unflip.setTranslate(0, SkScalarRound(surfaceBBox.height())); unflip.preScale(SK_Scalar1, -SK_Scalar1); SkISize size = SkISize::Make(SkScalarRound(surfaceBBox.width()), SkScalarRound(surfaceBBox.height())); SkPDFDevice pattern(size, size, unflip); SkCanvas canvas(&pattern); canvas.translate(-surfaceBBox.fLeft, -surfaceBBox.fTop); finalMatrix.preTranslate(surfaceBBox.fLeft, surfaceBBox.fTop); const SkBitmap* image = &fState.get()->fImage; int width = image->width(); int height = image->height(); SkShader::TileMode tileModes[2]; tileModes[0] = fState.get()->fImageTileModes[0]; tileModes[1] = fState.get()->fImageTileModes[1]; canvas.drawBitmap(*image, 0, 0); SkRect patternBBox = SkRect::MakeXYWH(-surfaceBBox.fLeft, -surfaceBBox.fTop, width, height); // Tiling is implied. First we handle mirroring. if (tileModes[0] == SkShader::kMirror_TileMode) { SkMatrix xMirror; xMirror.setScale(-1, 1); xMirror.postTranslate(2 * width, 0); canvas.drawBitmapMatrix(*image, xMirror); patternBBox.fRight += width; } if (tileModes[1] == SkShader::kMirror_TileMode) { SkMatrix yMirror; yMirror.setScale(SK_Scalar1, -SK_Scalar1); yMirror.postTranslate(0, 2 * height); canvas.drawBitmapMatrix(*image, yMirror); patternBBox.fBottom += height; } if (tileModes[0] == SkShader::kMirror_TileMode && tileModes[1] == SkShader::kMirror_TileMode) { SkMatrix mirror; mirror.setScale(-1, -1); mirror.postTranslate(2 * width, 2 * height); canvas.drawBitmapMatrix(*image, mirror); } // Then handle Clamping, which requires expanding the pattern canvas to // cover the entire surfaceBBox. // If both x and y are in clamp mode, we start by filling in the corners. // (Which are just a rectangles of the corner colors.) if (tileModes[0] == SkShader::kClamp_TileMode && tileModes[1] == SkShader::kClamp_TileMode) { SkPaint paint; SkRect rect; rect = SkRect::MakeLTRB(surfaceBBox.fLeft, surfaceBBox.fTop, 0, 0); if (!rect.isEmpty()) { paint.setColor(image->getColor(0, 0)); canvas.drawRect(rect, paint); } rect = SkRect::MakeLTRB(width, surfaceBBox.fTop, surfaceBBox.fRight, 0); if (!rect.isEmpty()) { paint.setColor(image->getColor(width - 1, 0)); canvas.drawRect(rect, paint); } rect = SkRect::MakeLTRB(width, height, surfaceBBox.fRight, surfaceBBox.fBottom); if (!rect.isEmpty()) { paint.setColor(image->getColor(width - 1, height - 1)); canvas.drawRect(rect, paint); } rect = SkRect::MakeLTRB(surfaceBBox.fLeft, height, 0, surfaceBBox.fBottom); if (!rect.isEmpty()) { paint.setColor(image->getColor(0, height - 1)); canvas.drawRect(rect, paint); } } // Then expand the left, right, top, then bottom. if (tileModes[0] == SkShader::kClamp_TileMode) { SkIRect subset = SkIRect::MakeXYWH(0, 0, 1, height); if (surfaceBBox.fLeft < 0) { SkBitmap left; SkAssertResult(image->extractSubset(&left, subset)); SkMatrix leftMatrix; leftMatrix.setScale(-surfaceBBox.fLeft, 1); leftMatrix.postTranslate(surfaceBBox.fLeft, 0); canvas.drawBitmapMatrix(left, leftMatrix); if (tileModes[1] == SkShader::kMirror_TileMode) { leftMatrix.postScale(SK_Scalar1, -SK_Scalar1); leftMatrix.postTranslate(0, 2 * height); canvas.drawBitmapMatrix(left, leftMatrix); } patternBBox.fLeft = 0; } if (surfaceBBox.fRight > width) { SkBitmap right; subset.offset(width - 1, 0); SkAssertResult(image->extractSubset(&right, subset)); SkMatrix rightMatrix; rightMatrix.setScale(surfaceBBox.fRight - width, 1); rightMatrix.postTranslate(width, 0); canvas.drawBitmapMatrix(right, rightMatrix); if (tileModes[1] == SkShader::kMirror_TileMode) { rightMatrix.postScale(SK_Scalar1, -SK_Scalar1); rightMatrix.postTranslate(0, 2 * height); canvas.drawBitmapMatrix(right, rightMatrix); } patternBBox.fRight = surfaceBBox.width(); } } if (tileModes[1] == SkShader::kClamp_TileMode) { SkIRect subset = SkIRect::MakeXYWH(0, 0, width, 1); if (surfaceBBox.fTop < 0) { SkBitmap top; SkAssertResult(image->extractSubset(&top, subset)); SkMatrix topMatrix; topMatrix.setScale(SK_Scalar1, -surfaceBBox.fTop); topMatrix.postTranslate(0, surfaceBBox.fTop); canvas.drawBitmapMatrix(top, topMatrix); if (tileModes[0] == SkShader::kMirror_TileMode) { topMatrix.postScale(-1, 1); topMatrix.postTranslate(2 * width, 0); canvas.drawBitmapMatrix(top, topMatrix); } patternBBox.fTop = 0; } if (surfaceBBox.fBottom > height) { SkBitmap bottom; subset.offset(0, height - 1); SkAssertResult(image->extractSubset(&bottom, subset)); SkMatrix bottomMatrix; bottomMatrix.setScale(SK_Scalar1, surfaceBBox.fBottom - height); bottomMatrix.postTranslate(0, height); canvas.drawBitmapMatrix(bottom, bottomMatrix); if (tileModes[0] == SkShader::kMirror_TileMode) { bottomMatrix.postScale(-1, 1); bottomMatrix.postTranslate(2 * width, 0); canvas.drawBitmapMatrix(bottom, bottomMatrix); } patternBBox.fBottom = surfaceBBox.height(); } } SkRefPtr<SkPDFArray> patternBBoxArray = new SkPDFArray; patternBBoxArray->unref(); // SkRefPtr and new both took a reference. patternBBoxArray->reserve(4); patternBBoxArray->appendScalar(patternBBox.fLeft); patternBBoxArray->appendScalar(patternBBox.fTop); patternBBoxArray->appendScalar(patternBBox.fRight); patternBBoxArray->appendScalar(patternBBox.fBottom); // Put the canvas into the pattern stream (fContent). SkRefPtr<SkStream> content = pattern.content(); content->unref(); // SkRefPtr and content() both took a reference. pattern.getResources(&fResources); setData(content.get()); insertName("Type", "Pattern"); insertInt("PatternType", 1); insertInt("PaintType", 1); insertInt("TilingType", 1); insert("BBox", patternBBoxArray.get()); insertScalar("XStep", patternBBox.width()); insertScalar("YStep", patternBBox.height()); insert("Resources", pattern.getResourceDict()); insert("Matrix", SkPDFUtils::MatrixToArray(finalMatrix))->unref(); fState.get()->fImage.unlockPixels(); }
SkPDFDict::SkPDFDict(const char type[]) { insertName("Type", type); }
SkPDFImage::SkPDFImage(SkStream* stream, const SkBitmap& bitmap, bool isAlpha, const SkIRect& srcRect) : fIsAlpha(isAlpha), fSrcRect(srcRect) { if (bitmap.isImmutable()) { fBitmap = bitmap; } else { bitmap.deepCopyTo(&fBitmap); fBitmap.setImmutable(); } if (stream != NULL) { this->setData(stream); fStreamValid = true; } else { fStreamValid = false; } SkColorType colorType = fBitmap.colorType(); insertName("Type", "XObject"); insertName("Subtype", "Image"); bool alphaOnly = (kAlpha_8_SkColorType == colorType); if (!isAlpha && alphaOnly) { // For alpha only images, we stretch a single pixel of black for // the color/shape part. SkAutoTUnref<SkPDFInt> one(new SkPDFInt(1)); insert("Width", one.get()); insert("Height", one.get()); } else { insertInt("Width", fSrcRect.width()); insertInt("Height", fSrcRect.height()); } if (isAlpha || alphaOnly) { insertName("ColorSpace", "DeviceGray"); } else if (kIndex_8_SkColorType == colorType) { SkAutoLockPixels alp(fBitmap); insert("ColorSpace", make_indexed_color_space(fBitmap.getColorTable()))->unref(); } else { insertName("ColorSpace", "DeviceRGB"); } int bitsPerComp = 8; if (kARGB_4444_SkColorType == colorType) { bitsPerComp = 4; } insertInt("BitsPerComponent", bitsPerComp); if (kRGB_565_SkColorType == colorType) { SkASSERT(!isAlpha); SkAutoTUnref<SkPDFInt> zeroVal(new SkPDFInt(0)); SkAutoTUnref<SkPDFScalar> scale5Val( new SkPDFScalar(8.2258f)); // 255/2^5-1 SkAutoTUnref<SkPDFScalar> scale6Val( new SkPDFScalar(4.0476f)); // 255/2^6-1 SkAutoTUnref<SkPDFArray> decodeValue(new SkPDFArray()); decodeValue->reserve(6); decodeValue->append(zeroVal.get()); decodeValue->append(scale5Val.get()); decodeValue->append(zeroVal.get()); decodeValue->append(scale6Val.get()); decodeValue->append(zeroVal.get()); decodeValue->append(scale5Val.get()); insert("Decode", decodeValue.get()); } }
static void add_type3_font_info(SkPDFCanon* canon, SkPDFDict* font, SkTypeface* typeface, const SkBitSet& subset, SkGlyphID firstGlyphID, SkGlyphID lastGlyphID) { const SkAdvancedTypefaceMetrics* metrics = SkPDFFont::GetMetrics(typeface, canon); SkASSERT(lastGlyphID >= firstGlyphID); // Remove unused glyphs at the end of the range. // Keep the lastGlyphID >= firstGlyphID invariant true. while (lastGlyphID > firstGlyphID && !subset.has(lastGlyphID)) { --lastGlyphID; } int unitsPerEm; auto cache = SkPDFFont::MakeVectorCache(typeface, &unitsPerEm); SkASSERT(cache); SkScalar emSize = (SkScalar)unitsPerEm; font->insertName("Subtype", "Type3"); // Flip about the x-axis and scale by 1/emSize. SkMatrix fontMatrix; fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize)); font->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix)); auto charProcs = sk_make_sp<SkPDFDict>(); auto encoding = sk_make_sp<SkPDFDict>("Encoding"); auto encDiffs = sk_make_sp<SkPDFArray>(); // length(firstGlyphID .. lastGlyphID) == lastGlyphID - firstGlyphID + 1 // plus 1 for glyph 0; SkASSERT(firstGlyphID > 0); SkASSERT(lastGlyphID >= firstGlyphID); int glyphCount = lastGlyphID - firstGlyphID + 2; // one other entry for the index of first glyph. encDiffs->reserve(glyphCount + 1); encDiffs->appendInt(0); // index of first glyph auto widthArray = sk_make_sp<SkPDFArray>(); widthArray->reserve(glyphCount); SkIRect bbox = SkIRect::MakeEmpty(); sk_sp<SkPDFStream> emptyStream; for (SkGlyphID gID : SingleByteGlyphIdIterator(firstGlyphID, lastGlyphID)) { bool skipGlyph = gID != 0 && !subset.has(gID); SkString characterName; SkScalar advance = 0.0f; SkIRect glyphBBox; if (skipGlyph) { characterName.set("g0"); } else { characterName.printf("g%X", gID); const SkGlyph& glyph = cache->getGlyphIDMetrics(gID); advance = SkFloatToScalar(glyph.fAdvanceX); glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight); bbox.join(glyphBBox); const SkPath* path = cache->findPath(glyph); if (path && !path->isEmpty()) { SkDynamicMemoryWStream content; setGlyphWidthAndBoundingBox(SkFloatToScalar(glyph.fAdvanceX), glyphBBox, &content); SkPDFUtils::EmitPath(*path, SkPaint::kFill_Style, &content); SkPDFUtils::PaintPath(SkPaint::kFill_Style, path->getFillType(), &content); charProcs->insertObjRef( characterName, sk_make_sp<SkPDFStream>( std::unique_ptr<SkStreamAsset>(content.detachAsStream()))); } else { if (!emptyStream) { emptyStream = sk_make_sp<SkPDFStream>( std::unique_ptr<SkStreamAsset>( new SkMemoryStream((size_t)0))); } charProcs->insertObjRef(characterName, emptyStream); } } encDiffs->appendName(characterName.c_str()); widthArray->appendScalar(advance); } encoding->insertObject("Differences", std::move(encDiffs)); font->insertInt("FirstChar", 0); font->insertInt("LastChar", lastGlyphID - firstGlyphID + 1); /* FontBBox: "A rectangle expressed in the glyph coordinate system, specifying the font bounding box. This is the smallest rectangle enclosing the shape that would result if all of the glyphs of the font were placed with their origins coincident and then filled." */ auto fontBBox = sk_make_sp<SkPDFArray>(); fontBBox->reserve(4); fontBBox->appendInt(bbox.left()); fontBBox->appendInt(bbox.bottom()); fontBBox->appendInt(bbox.right()); fontBBox->appendInt(bbox.top()); font->insertObject("FontBBox", std::move(fontBBox)); font->insertName("CIDToGIDMap", "Identity"); if (metrics && metrics->fGlyphToUnicode.count() > 0) { font->insertObjRef("ToUnicode", SkPDFMakeToUnicodeCmap(metrics->fGlyphToUnicode, &subset, false, firstGlyphID, lastGlyphID)); } auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); int32_t fontDescriptorFlags = kPdfSymbolic; if (metrics) { // Type3 FontDescriptor does not require all the same fields. descriptor->insertName("FontName", metrics->fPostScriptName); descriptor->insertInt("ItalicAngle", metrics->fItalicAngle); fontDescriptorFlags |= (int32_t)metrics->fStyle; // Adobe requests CapHeight, XHeight, and StemV be added // to "greatly help our workflow downstream". if (metrics->fCapHeight != 0) { descriptor->insertInt("CapHeight", metrics->fCapHeight); } if (metrics->fStemV != 0) { descriptor->insertInt("StemV", metrics->fStemV); } SkScalar xHeight = cache->getFontMetrics().fXHeight; if (xHeight != 0) { descriptor->insertScalar("XHeight", xHeight); } } descriptor->insertInt("Flags", fontDescriptorFlags); font->insertObjRef("FontDescriptor", std::move(descriptor)); font->insertObject("Widths", std::move(widthArray)); font->insertObject("Encoding", std::move(encoding)); font->insertObject("CharProcs", std::move(charProcs)); }
void SkPDFType0Font::getFontSubset(SkPDFCanon* canon) { const SkAdvancedTypefaceMetrics* metricsPtr = SkPDFFont::GetMetrics(this->typeface(), canon); SkASSERT(metricsPtr); if (!metricsPtr) { return; } const SkAdvancedTypefaceMetrics& metrics = *metricsPtr; SkASSERT(can_embed(metrics)); SkAdvancedTypefaceMetrics::FontType type = this->getType(); SkTypeface* face = this->typeface(); SkASSERT(face); auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); uint16_t emSize = SkToU16(this->typeface()->getUnitsPerEm()); add_common_font_descriptor_entries(descriptor.get(), metrics, emSize , 0); int ttcIndex; std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex)); size_t fontSize = fontAsset ? fontAsset->getLength() : 0; if (0 == fontSize) { SkDebugf("Error: (SkTypeface)(%p)::openStream() returned " "empty stream (%p) when identified as kType1CID_Font " "or kTrueType_Font.\n", face, fontAsset.get()); } else { switch (type) { case SkAdvancedTypefaceMetrics::kTrueType_Font: { #ifdef SK_PDF_USE_SFNTLY if (!SkToBool(metrics.fFlags & SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag)) { sk_sp<SkPDFStream> subsetStream = get_subset_font_stream( std::move(fontAsset), this->glyphUsage(), metrics.fFontName.c_str(), ttcIndex); if (subsetStream) { descriptor->insertObjRef("FontFile2", std::move(subsetStream)); break; } // If subsetting fails, fall back to original font data. fontAsset.reset(face->openStream(&ttcIndex)); SkASSERT(fontAsset); SkASSERT(fontAsset->getLength() == fontSize); if (!fontAsset || fontAsset->getLength() == 0) { break; } } #endif // SK_PDF_USE_SFNTLY auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontAsset)); fontStream->dict()->insertInt("Length1", fontSize); descriptor->insertObjRef("FontFile2", std::move(fontStream)); break; } case SkAdvancedTypefaceMetrics::kType1CID_Font: { auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontAsset)); fontStream->dict()->insertName("Subtype", "CIDFontType0C"); descriptor->insertObjRef("FontFile3", std::move(fontStream)); break; } default: SkASSERT(false); } } auto newCIDFont = sk_make_sp<SkPDFDict>("Font"); newCIDFont->insertObjRef("FontDescriptor", std::move(descriptor)); newCIDFont->insertName("BaseFont", metrics.fPostScriptName); switch (type) { case SkAdvancedTypefaceMetrics::kType1CID_Font: newCIDFont->insertName("Subtype", "CIDFontType0"); break; case SkAdvancedTypefaceMetrics::kTrueType_Font: newCIDFont->insertName("Subtype", "CIDFontType2"); newCIDFont->insertName("CIDToGIDMap", "Identity"); break; default: SkASSERT(false); } auto sysInfo = sk_make_sp<SkPDFDict>(); sysInfo->insertString("Registry", "Adobe"); sysInfo->insertString("Ordering", "Identity"); sysInfo->insertInt("Supplement", 0); newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo)); int16_t defaultWidth = 0; { int emSize; auto glyphCache = SkPDFFont::MakeVectorCache(face, &emSize); sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray( glyphCache.get(), &this->glyphUsage(), SkToS16(emSize), &defaultWidth); if (widths && widths->size() > 0) { newCIDFont->insertObject("W", std::move(widths)); } newCIDFont->insertScalar( "DW", scaleFromFontUnits(defaultWidth, SkToS16(emSize))); } //////////////////////////////////////////////////////////////////////////// this->insertName("Subtype", "Type0"); this->insertName("BaseFont", metrics.fPostScriptName); this->insertName("Encoding", "Identity-H"); auto descendantFonts = sk_make_sp<SkPDFArray>(); descendantFonts->appendObjRef(std::move(newCIDFont)); this->insertObject("DescendantFonts", std::move(descendantFonts)); if (metrics.fGlyphToUnicode.count() > 0) { this->insertObjRef("ToUnicode", SkPDFMakeToUnicodeCmap(metrics.fGlyphToUnicode, &this->glyphUsage(), multiByteGlyphs(), firstGlyphID(), lastGlyphID())); } SkDEBUGCODE(fPopulated = true); return; }
int adjustInfo(Member_t *id, int i) { int j, IDnum = 0, valid = -1, count = 0; int choice = 0; char tempname[NAME_MAXCHAR]; // 이름 수정 정보를 되돌리기 위한 temp 변수 char tempaddress[ADDRESS_MAXCHAR]; // 주소 수정 정보를 되돌리기 위한 temp 변수 char tempcellphone[CELLPHONE_MAXCHAR]; // 전화번호 수정 정보를 되돌리기 위한 temp 변수 if (i != -1){ while (choice != -1){ choice = adjustInfoMenuChoice(); switch (choice) { case '1': adjustCell(count); gotoxy(6, 17); printf("① 학번 : "); IDnum = insertStudentNum(23, 17, 1); if (IDnum > -1) IDnum = repeatStudentIDCheck(id, IDnum); if (IDnum > -1) adjustInfoInputStudentID(id, IDnum, i); break; case '2': while (valid == -1){ adjustCell(count); gotoxy(6, 17); printf("② 이름 : "); strcpy(tempname, id[i].Name); valid = insertName(23, 17, id[i].Name, 1); if (valid > -1) adjustInfoInputName(id, i); else strcpy(id[i].Name, tempname); count++; } valid = -1; count = 0; break; case '3': while (valid == -1){ adjustCell(count); gotoxy(6, 17); printf("③ 주소 : "); strcpy(tempaddress, id[i].Address); valid = insertAddress(23, 17, id[i].Address, 1); if (valid > -1) adjustInfoInputAddress(id, i); else strcpy(id[i].Address, tempaddress); count++; } valid = -1; count = 0; break; case '4': while (valid == -1){ adjustCell(count); gotoxy(6, 17); printf("④ 전화번호 : "); gotoxy(26, 17); printf(" - - "); strcpy(tempcellphone, id[i].Cellphone); valid = insertCellphone(23, 17, id[i].Cellphone, 1); if (valid > -1){ // 전화번호 중복 Check for (j = 1; id[j].Studentnum != 0; j++){ if (i == j); else if (strcmp(id[j].Cellphone, id[i].Cellphone) == 0) { // 전화 번호가 같다면 -1을 반환 repeatCellphoneErrorOn(1); valid = -1; break; } } } if (valid != -1) { adjustInfoInputCellphone(id, i); break; } else strcpy(id[i].Cellphone, tempcellphone); count++; } break; } gotoxy(0, 16); lineClear(); gotoxy(0, 17); lineClear(); gotoxy(0, 18); lineClear(); } } return -1; }
static SkPDFIndirectReference make_function_shader(SkPDFDocument* doc, const SkPDFGradientShader::Key& state) { SkPoint transformPoints[2]; const SkShader::GradientInfo& info = state.fInfo; SkMatrix finalMatrix = state.fCanvasTransform; finalMatrix.preConcat(state.fShaderTransform); bool doStitchFunctions = (state.fType == SkShader::kLinear_GradientType || state.fType == SkShader::kRadial_GradientType || state.fType == SkShader::kConical_GradientType) && (SkTileMode)info.fTileMode == SkTileMode::kClamp && !finalMatrix.hasPerspective(); int32_t shadingType = 1; auto pdfShader = SkPDFMakeDict(); // The two point radial gradient further references // state.fInfo // in translating from x, y coordinates to the t parameter. So, we have // to transform the points and radii according to the calculated matrix. if (doStitchFunctions) { pdfShader->insertObject("Function", gradientStitchCode(info)); shadingType = (state.fType == SkShader::kLinear_GradientType) ? 2 : 3; auto extend = SkPDFMakeArray(); extend->reserve(2); extend->appendBool(true); extend->appendBool(true); pdfShader->insertObject("Extend", std::move(extend)); std::unique_ptr<SkPDFArray> coords; if (state.fType == SkShader::kConical_GradientType) { SkScalar r1 = info.fRadius[0]; SkScalar r2 = info.fRadius[1]; SkPoint pt1 = info.fPoint[0]; SkPoint pt2 = info.fPoint[1]; FixUpRadius(pt1, r1, pt2, r2); coords = SkPDFMakeArray(pt1.x(), pt1.y(), r1, pt2.x(), pt2.y(), r2); } else if (state.fType == SkShader::kRadial_GradientType) { const SkPoint& pt1 = info.fPoint[0]; coords = SkPDFMakeArray(pt1.x(), pt1.y(), 0, pt1.x(), pt1.y(), info.fRadius[0]); } else { const SkPoint& pt1 = info.fPoint[0]; const SkPoint& pt2 = info.fPoint[1]; coords = SkPDFMakeArray(pt1.x(), pt1.y(), pt2.x(), pt2.y()); } pdfShader->insertObject("Coords", std::move(coords)); } else { // Depending on the type of the gradient, we want to transform the // coordinate space in different ways. transformPoints[0] = info.fPoint[0]; transformPoints[1] = info.fPoint[1]; switch (state.fType) { case SkShader::kLinear_GradientType: break; case SkShader::kRadial_GradientType: transformPoints[1] = transformPoints[0]; transformPoints[1].fX += info.fRadius[0]; break; case SkShader::kConical_GradientType: { transformPoints[1] = transformPoints[0]; transformPoints[1].fX += SK_Scalar1; break; } case SkShader::kSweep_GradientType: transformPoints[1] = transformPoints[0]; transformPoints[1].fX += SK_Scalar1; break; case SkShader::kColor_GradientType: case SkShader::kNone_GradientType: default: return SkPDFIndirectReference(); } // Move any scaling (assuming a unit gradient) or translation // (and rotation for linear gradient), of the final gradient from // info.fPoints to the matrix (updating bbox appropriately). Now // the gradient can be drawn on on the unit segment. SkMatrix mapperMatrix; unit_to_points_matrix(transformPoints, &mapperMatrix); finalMatrix.preConcat(mapperMatrix); // Preserves as much as possible in the final matrix, and only removes // the perspective. The inverse of the perspective is stored in // perspectiveInverseOnly matrix and has 3 useful numbers // (p0, p1, p2), while everything else is either 0 or 1. // In this way the shader will handle it eficiently, with minimal code. SkMatrix perspectiveInverseOnly = SkMatrix::I(); if (finalMatrix.hasPerspective()) { if (!split_perspective(finalMatrix, &finalMatrix, &perspectiveInverseOnly)) { return SkPDFIndirectReference(); } } SkRect bbox; bbox.set(state.fBBox); if (!SkPDFUtils::InverseTransformBBox(finalMatrix, &bbox)) { return SkPDFIndirectReference(); } SkDynamicMemoryWStream functionCode; SkShader::GradientInfo infoCopy = info; if (state.fType == SkShader::kConical_GradientType) { SkMatrix inverseMapperMatrix; if (!mapperMatrix.invert(&inverseMapperMatrix)) { return SkPDFIndirectReference(); } inverseMapperMatrix.mapPoints(infoCopy.fPoint, 2); infoCopy.fRadius[0] = inverseMapperMatrix.mapRadius(info.fRadius[0]); infoCopy.fRadius[1] = inverseMapperMatrix.mapRadius(info.fRadius[1]); } switch (state.fType) { case SkShader::kLinear_GradientType: linearCode(infoCopy, perspectiveInverseOnly, &functionCode); break; case SkShader::kRadial_GradientType: radialCode(infoCopy, perspectiveInverseOnly, &functionCode); break; case SkShader::kConical_GradientType: twoPointConicalCode(infoCopy, perspectiveInverseOnly, &functionCode); break; case SkShader::kSweep_GradientType: sweepCode(infoCopy, perspectiveInverseOnly, &functionCode); break; default: SkASSERT(false); } pdfShader->insertObject( "Domain", SkPDFMakeArray(bbox.left(), bbox.right(), bbox.top(), bbox.bottom())); auto domain = SkPDFMakeArray(bbox.left(), bbox.right(), bbox.top(), bbox.bottom()); std::unique_ptr<SkPDFArray> rangeObject = SkPDFMakeArray(0, 1, 0, 1, 0, 1); pdfShader->insertRef("Function", make_ps_function(functionCode.detachAsStream(), std::move(domain), std::move(rangeObject), doc)); } pdfShader->insertInt("ShadingType", shadingType); pdfShader->insertName("ColorSpace", "DeviceRGB"); SkPDFDict pdfFunctionShader("Pattern"); pdfFunctionShader.insertInt("PatternType", 2); pdfFunctionShader.insertObject("Matrix", SkPDFUtils::MatrixToArray(finalMatrix)); pdfFunctionShader.insertObject("Shading", std::move(pdfShader)); return doc->emit(pdfFunctionShader); }
sk_sp<SkPDFDict> SkPDFGraphicState::MakeNoSmaskGraphicState() { auto noSMaskGS = sk_make_sp<SkPDFDict>("ExtGState"); noSMaskGS->insertName("SMask", "None"); return noSMaskGS; }