#1 2018-11-21 15:54:24

jeanmilost
Member
Registered: 2016-01-21
Posts: 35

Can SynPDF be used with Direct2D/DirectWrite?

I'm interested to use Direct2D/DirectWrite to draw a PDF content. One of the reason is that I want to use the provided colored font system, other is because its offers a improved non Latin languages support, and it resolves better the font fallback.

So I tried to get the GDI canvas from my PDF page, to create a Direct2D canvas above it, and to draw text on it. However I just get a black rectangle as result.

My question is: Is there a way to draw on a PDF page using Direct2D, and if yes, how to achieve that?

NOTE here is the code I actually use to try to draw a text with Direct2D. Of course I tried several configurations, but I always get the same result

void TMainForm::DrawWithD2D()
{
    const std::wstring text = L"This is an example text!!!";

    std::auto_ptr<TPdfDocumentGDI> pPdfDoc(new TPdfDocumentGDI(false, 0, false, NULL));

    // populate PDF header
    pPdfDoc->Info->Title                = L"D2D Demo";
    pPdfDoc->Info->Author               = L"Ursa Minor";
    pPdfDoc->Info->Creator              = L"PDF Demo";
    pPdfDoc->Info->CreationDate         = ::Now();
    pPdfDoc->DefaultPaperSize           = Synpdf::psA4;
    pPdfDoc->UseFontFallBack            = true;
    pPdfDoc->UseUniscribe               = true;
    pPdfDoc->FontFallBackNames          = "Arial";
    pPdfDoc->KerningHHorzScale          = 96.5f;
    pPdfDoc->PDFA1                      = false;
    pPdfDoc->GeneratePDF15File          = true;
    pPdfDoc->ScreenLogPixels            = 96;
    pPdfDoc->UseMetaFileTextPositioning = tpExactTextCharacterPositining;

    // create and add first page
    pPdfDoc->AddPage();

    TCanvas* pCanvas = pPdfDoc->VCLCanvas;

    const TRect rect(20,20, 320, 220);

    ::D2D1_RECT_F drawRect;
    drawRect.left   = rect.Left;
    drawRect.top    = rect.Top;
    drawRect.right  = rect.Right;
    drawRect.bottom = rect.Bottom;

    // get Direct2D canvas
    std::unique_ptr<TDirect2DCanvas> pD2DCanvas(new TDirect2DCanvas(pCanvas->Handle, rect));

    // set antialiasing mode
    pD2DCanvas->RenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);

    ::ID2D1SolidColorBrush* pBrush = NULL;

    // create solid color brush
    pD2DCanvas->RenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &pBrush);

    if (!pBrush)
        return;

    // get (or create) the DirectWrite factory
    _di_IDWriteFactory pDirectWrite = WDirect2DHelper::DWriteFactory(DWRITE_FACTORY_TYPE_SHARED);

    if (!pDirectWrite)
        return;

    // configure and apply new rendering parameters for DirectWrite
    _di_IDWriteRenderingParams renderParams;
    pDirectWrite->CreateCustomRenderingParams(1.0f, 0.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_RGB,
            DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC, &renderParams);
    pD2DCanvas->RenderTarget->SetTextRenderingParams(renderParams);

    // get DirectWrite text format object
    _di_IDWriteTextFormat pFormat = pD2DCanvas->Font->Handle;

    // found it?
    if (!pFormat)
        return;

    // set horiz alignment
    pFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);

    // set vert alignment
    pFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR);

    // set word wrapping mode
    pFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_WRAP);

    IDWriteInlineObject* pInlineObject = NULL;

    ::DWRITE_TRIMMING trimming;
    trimming.delimiter      = 0;
    trimming.delimiterCount = 0;
    trimming.granularity    = DWRITE_TRIMMING_GRANULARITY_NONE;

    // set text trimming
    pFormat->SetTrimming(&trimming, pInlineObject);

    try
    {
        pD2DCanvas->BeginDraw();

        // draw the text
        pD2DCanvas->RenderTarget->DrawText(text.c_str(), text.length(), pFormat, drawRect, pBrush,
                D2D1_DRAW_TEXT_OPTIONS_NONE);
    }
    __finally
    {
        pD2DCanvas->EndDraw();
    }

    pPdfDoc->SaveToFile(L"test.pdf");

    ::ShellExecute(Handle, L"open", L"test.pdf", L"", L"", 0);
}

Last edited by jeanmilost (2018-11-21 16:05:32)

Offline

#2 2018-11-21 16:21:15

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,244
Website

Re: Can SynPDF be used with Direct2D/DirectWrite?

The GDI canvas is... a GDI canvas... not a GDI+ canvas nor a Direct2D canvas.
So you need to convert the Direct2D calls into PDF calls, perhaps via GDI/EMF enumeration.
But the extended features you expect won't be available in the GDI/EMF enumeration, and need proper PDF generation, which is not available yet.

Offline

#3 2018-11-21 16:46:34

jeanmilost
Member
Registered: 2016-01-21
Posts: 35

Re: Can SynPDF be used with Direct2D/DirectWrite?

Thank you for the answer. I was expecting something like this.

However is it expected to expand SynPDF to support Direct2D in the future?

Offline

#4 2018-11-22 09:18:48

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,244
Website

Re: Can SynPDF be used with Direct2D/DirectWrite?

Nothing like this is planned, but any input is welcome!

Offline

Board footer

Powered by FluxBB