question

kasmer-2455 avatar image
0 Votes"
kasmer-2455 asked XiaopoYang-MSFT edited

SetTransformLocal question.

Hello,

I have the following code;

 IXpsOMMatrixTransform* rawGeomToPhys;
                             result = xpsObjectFactory->CreateMatrixTransform(&combinedMatrix, &rawGeomToPhys);
    
                             IXpsOMVisualCollection* pageVisuals;
                             result = page->GetVisuals(&pageVisuals);
    
                             result = pageVisuals->Append(scaleCanvas);
    
                             scaleCanvas->SetTransformLocal(rawGeomToPhys);
                                
                             IXpsOMVisual* visual = NULL;
                             XPS_OBJECT_TYPE  visualType;
    
                             UINT32 count;
                             UINT32 thisVisual;
    
                             pageVisuals->GetCount(&count);
                             thisVisual = 0;
                             while (thisVisual < count) 
                             {
                                 result = pageVisuals->GetAt(thisVisual, &visual);
    
                                 result = visual->GetType(&visualType);
    
                                 if (visualType == XPS_OBJECT_TYPE_CANVAS)
                                 {
                                     result = visual->SetTransformLocal(rawGeomToPhys);
                                 }
    
                                 if (NULL != visual) { visual->Release(); visual = NULL; }
                                 thisVisual++;
                             }

If I remove the following line;

 scaleCanvas->SetTransformLocal(rawGeomToPhys);

the scale and translate on the matrix takes effect; however, the pages are produced upside down and content is mirrored.

If I keep the aforementioned line of code, the scale and translate on the matrix has no effect; however, the pages produced come out scaled to the page size and in proper format (upside and not mirrored) (must be using a default value for the scaling and translation)

How can I keep;

 scaleCanvas->SetTransformLocal(rawGeomToPhys);

in my code but still apply the matrix scale and translate which is something like;

 combinedMatrix.scale(0.5, 0.5);
 combinedMatrix.translate(y, x);




windows-apic++
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

What‘s the effect if commenting the two SetTransformLocal? Could you please show a minimal, reproducible sample without private information?

0 Votes 0 ·

If I comment out both SetTransformLocal's, then it prints the same way as if the following line was kept in; scaleCanvas->SetTransformLocal(rawGeomToPhys); AKA it has a default matrix values applied which I assume is 1.0 for scaling.

I can either have both commented out and removed or both kept in, but either way I need to be able to apply a translate for the centering of the page content on different paper sizes.

Do you know why in the code I provided, why combinedMatrix is not being applied when scaleCanvas->SetTransformLocal(rawGeomToPhys); is there, since I need scaleCanvas->SetTransformLocal(rawGeomToPhys); to be there anyways.

0 Votes 0 ·

Can you SetTransformLocal before result = pageVisuals->Append(scaleCanvas);?




0 Votes 0 ·
Show more comments

1 Answer

XiaopoYang-MSFT avatar image
0 Votes"
XiaopoYang-MSFT answered XiaopoYang-MSFT edited

Perhaps you should code according to the following code from chromium, especially the order of SetTransformLocal and Append, etc. I suppose there is no trick about SetTransformLocal.:

 bool SkXPSDevice::endSheet() {
     //XPS is fixed at 96dpi (XPS Spec 11.1).
     static const float xpsDPI = 96.0f;
     static const float inchesPerMeter = 10000.0f / 254.0f;
     static const float targetUnitsPerMeter = xpsDPI * inchesPerMeter;
     const float scaleX = targetUnitsPerMeter
                        / SkScalarToFLOAT(this->fCurrentUnitsPerMeter.fX);
     const float scaleY = targetUnitsPerMeter
                        / SkScalarToFLOAT(this->fCurrentUnitsPerMeter.fY);
     //Create the scale canvas.
     SkTScopedComPtr<IXpsOMCanvas> scaleCanvas;
     HRBM(this->fXpsFactory->CreateCanvas(&scaleCanvas),
          "Could not create scale canvas.");
     SkTScopedComPtr<IXpsOMVisualCollection> scaleCanvasVisuals;
     HRBM(scaleCanvas->GetVisuals(&scaleCanvasVisuals),
          "Could not get scale canvas visuals.");
     SkTScopedComPtr<IXpsOMMatrixTransform> geomToPhys;
     XPS_MATRIX rawGeomToPhys = { scaleX, 0, 0, scaleY, 0, 0, };
     HRBM(this->fXpsFactory->CreateMatrixTransform(&rawGeomToPhys, &geomToPhys),
          "Could not create geometry to physical transform.");
     HRBM(scaleCanvas->SetTransformLocal(geomToPhys.get()),
          "Could not set transform on scale canvas.");
     //Add the content canvas to the scale canvas.
     HRBM(scaleCanvasVisuals->Append(this->fCurrentXpsCanvas.get()),
          "Could not add base canvas to scale canvas.");
     //Create the page.
     XPS_SIZE pageSize = {
         SkScalarToFLOAT(this->fCurrentCanvasSize.width()) * scaleX,
         SkScalarToFLOAT(this->fCurrentCanvasSize.height()) * scaleY,
     };
     SkTScopedComPtr<IXpsOMPage> page;
     HRB(this->createXpsPage(pageSize, &page));
     SkTScopedComPtr<IXpsOMVisualCollection> pageVisuals;
     HRBM(page->GetVisuals(&pageVisuals), "Could not get page visuals.");
     //Add the scale canvas to the page.
     HRBM(pageVisuals->Append(scaleCanvas.get()),
          "Could not add scale canvas to page.");
     //Create the package writer if it hasn't been created yet.
     if (NULL == this->fPackageWriter.get()) {
         SkTScopedComPtr<IXpsOMImageResource> image;
         //Ignore return, thumbnail is completely optional.
         this->createXpsThumbnail(page.get(), 0, &image);
         HRB(this->initXpsDocumentWriter(image.get()));
     }
     HRBM(this->fPackageWriter->AddPage(page.get(),
                                        &pageSize,
                                        NULL,
                                        NULL,
                                        NULL,
                                        NULL),
          "Could not write the page.");
     this->fCurrentXpsCanvas.reset();
     return true;
 }

and

 void SkXPSDevice::drawDevice(const SkDraw& d, SkBaseDevice* dev,
                              int x, int y,
                              const SkPaint&) {
     SkXPSDevice* that = static_cast<SkXPSDevice*>(dev);
     SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
     XPS_MATRIX rawTransform = {
         1.0f,
         0.0f,
         0.0f,
         1.0f,
         static_cast<FLOAT>(x),
         static_cast<FLOAT>(y),
     };
     HRVM(this->fXpsFactory->CreateMatrixTransform(&rawTransform, &xpsTransform),
          "Could not create layer transform.");
     HRVM(that->fCurrentXpsCanvas->SetTransformLocal(xpsTransform.get()),
          "Could not set layer transform.");
     //Get the current visual collection and add the layer to it.
     SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
     HRVM(this->fCurrentXpsCanvas->GetVisuals(&currentVisuals),
          "Could not get current visuals for layer.");
     HRVM(currentVisuals->Append(that->fCurrentXpsCanvas.get()),
          "Could not add layer to current visuals.");
 }




5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.