Comments (7)
PDFModifiedPage
has GetCurrentResourcesDictionary
that you can use for the same purpose as yo would use GetResourcesDictionary
for a regular page.
The rest is the same.
here's an example for creating modified page, content context and writing the page.
from pdf-writer.
Hi :)
To write Oblique text all you have to do is find a font that's oblique. Same as you would for writing text in bold or italic. For example, here is a courier oblique version - https://fontsgeek.com/fonts/Courier-Oblique.
As for opacity, there are a few discussions in HummusJS (the JS version of this lib) and i think the most fitting is this one. While it discusses regular paths and not text, the solution is the same. Please have a look, it might be a shorter version of a longer explanation following here. If you want help with converting to C++ do let me know and i'll help.
The point is to apply a graphic static prior to drawing the said text (or path) that includes an opacity factor in it.
There are 3 steps to this:
- Creating the external graphic state dictionary
- Referring to this graphic state from the page or form that you want to draw the text in and giving it a name
- Applying the graphic state with the
GS
operator providing it the said name.
Now you just draw the text with the usual text operators and the opacity defined in the graphic state will be applied.
here's an example of how to create the graphic state dict:
ObjectsContext *objCxt = pdfWriter->GetObjectsContext();
ObjectIDType gsId = objCxt->StartNewIndirectObject();
DictionaryContext* dict = objCxt->StartDictionary()
dict->WriteKey("type");
dict->WriteNameValue("ExtGState");
dict->WriteKey("ca");
objCxt->WriteNumber(0.5);
objCxt->EndLine();
objCxt->EndDictionary(dict);
gsId
holds the object number for this dictionary. you will use it for the 2nd step.
here's an example of referring to the dictionary from a page resources dictionary:
string gstateName = myPage->GetResourcesDictionary().AddExtGStateMapping(gsId);
gstateName
now holds the name of the extgstate that can be used within the page drawing context to apply the state, and allow drawing entities with 0.5 opacity.
For example:
PageContentContext* cxt = myPage->StartPageContentContext(page);
AbstractContentContext::TextOptions textOptions(
pdfWriter.GetFontForFile("fonts/arial.ttf"),
14,
AbstractContentContext::eGray,
0);
cxt->q();
cxt->gs(gstateName);
cxt->WriteText(75,805,"Yolo",textOptions);
cxt->Q();
That should be it. You can use the more low level methods to write the text, or alternatively draw a path...doesn't matter as long as you call the gs
command prior to set the opacity level.
It is OK to combine stages 2 and 3, like this:
cxt->gs(myPage->GetResourcesDictionary().AddExtGStateMapping(gsId));
p.s. there's an example here (and links to code) that shows how to create a single watermark in a form and then reuse that form in multiple pages. again in JS, but can be translated to the C++ operators by mostly moving from camelcasing to titlecasing.
from pdf-writer.
Thanks for replying
Here is my code now ..
pdfWriter.StartPDF(input, ePDFVersion13);
ObjectsContext objCtx = pdfWriter.GetObjectsContext();
ObjectIDType gsID = objCtx.StartNewIndirectObject();
DictionaryContext* dict = objCtx.StartDictionary();
dict->WriteKey("type");
dict->WriteNameValue("ExtGState");
dict->WriteKey("ca");
objCtx.WriteInteger(0.5); //// cannot find WriteNumber
objCtx.EndLine();
objCtx.EndDictionary(dict);
auto* page = new PDFPage();
page->SetMediaBox(PDFRectangle(0,0,595,842));
std::string gsName = page->GetResourcesDictionary().AddExtGStateMapping(gsID);
PageContentContext* pageContentContext = pdfWriter.StartPageContentContext(page);
PDFUsedFont* font = pdfWriter.GetFontForFile(font_path);
pageContentContext->q();
pageContentContext->gs(gsName);
pageContentContext->BT();
pageContentContext->k(0, 100, 100, 0);
pageContentContext->Tf(font, font_size);
pageContentContext->Tm(1,0,0,1,100,100);
pageContentContext->Tj("Test Text");
pageContentContext->ET();
pageContentContext->Q();
pdfWriter.EndPageContentContext(pageContentContext);
pdfWriter.WritePageAndRelease(page);
pdfWriter.EndPDF();
But opacity not changing
from pdf-writer.
Hi,
Sorry for not providing a proper example. I just translated lazily from the JS and this resulted in some errors.
To directly deal with errors in the example:
- this
ObjectsContext objCtx = pdfWriter.GetObjectsContext();
should change to thisObjectsContext& objCtx = pdfWriter.GetObjectsContext();
otherwise, we're just creating a copy of the objects context and not actual reference, so what records it has gets lost (specifically - the dictionary object gets overwritten by a later object. - this
objCtx.WriteInteger(0.5);
should change to thisobjCtx.WriteDouble(0.5);
, otherwise int will get rounded to 0 and you will see no watermark. - the indirect object should be ended with
objCtx.EndIndirectObject();
PDFVersion should probably also change to 14 and not stay in 13, as things like "ca" key are only supported from 14...but that's not a biggy, i think acrobat ignores it.
So the code should be:
pdfWriter.StartPDF(input, ePDFVersion14);
ObjectsContext& objCtx = pdfWriter.GetObjectsContext();
ObjectIDType gsID = objCtx.StartNewIndirectObject();
DictionaryContext* dict = objCtx.StartDictionary();
dict->WriteKey("type");
dict->WriteNameValue("ExtGState");
dict->WriteKey("ca");
objCtx.WriteDouble(0.5);
objCtx.EndLine();
objCtx.EndDictionary(dict);
objCtx.EndIndirectObject();
auto* page = new PDFPage();
page->SetMediaBox(PDFRectangle(0,0,595,842));
std::string gsName = page->GetResourcesDictionary().AddExtGStateMapping(gsID);
PageContentContext* pageContentContext = pdfWriter.StartPageContentContext(page);
PDFUsedFont* font = pdfWriter.GetFontForFile(font_path);
pageContentContext->q();
pageContentContext->gs(gsName);
pageContentContext->BT();
pageContentContext->k(0, 100, 100, 0);
pageContentContext->Tf(font, font_size);
pageContentContext->Tm(1,0,0,1,100,100);
pageContentContext->Tj("Test Text");
pageContentContext->ET();
pageContentContext->Q();
pdfWriter.EndPageContentContext(pageContentContext);
pdfWriter.WritePageAndRelease(page);
pdfWriter.EndPDF();
I added a test called WatermarkTest now to serve as an example.
It also features more higher level commands that's available for writing text and using the dictionary api to write the double.
from pdf-writer.
Worked like a charm
Thanks :)
from pdf-writer.
How to use it in modified page ? Not new empty page
Specifically this line
std::string gsName = page->GetResourcesDictionary().AddExtGStateMapping(gsID);
from pdf-writer.
Hi,
for the sake of another project, for supporting color emojis (#223) i added a SetOpacity
operator on content context. hummus manages the creation of relevant extgstate dicts in the background, so you don't have to worry about it. the implementation is also available on the higher level commands with Text options and graphic options now including an opacity factor.
See example here.
from pdf-writer.
Related Issues (20)
- Can not modify a document by creating a new form XObject and using it in one of the pages HOT 3
- [Question] - pdf to image HOT 1
- Question about attachments HOT 2
- some example projects in wiki are missing HOT 2
- Streams objects writing problem HOT 2
- Missing lib.obj file HOT 3
- Android Build Workflow HOT 3
- CIDSet encoding does not conform with ISO 19005-2:2011, ISO 19005-3:2012 (PDF/A-2b or PDF/A-3b) HOT 21
- annotations are lost with PDFDocumentCopyingContext::AppendPDFPageFromPDF HOT 3
- How to draw Bezier curves using PDF-Witer library? HOT 2
- Parse a screenplay into scene objects? HOT 2
- color emojis HOT 16
- Links are removed when documents are merged HOT 8
- Color inversion problem occurs when exporting images HOT 1
- infinite loop HOT 2
- Crash when WriteUsedFontsDefinitions HOT 17
- Publish to github releases without PDFWriterTesting HOT 4
- U3D support, 10 years later HOT 10
- `Segmentation fault (core dumped)` just for adding `PDFWriter pdfWriter` in the `h` file HOT 11
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pdf-writer.