Dynamics Ax printing logo’s from batch

Hi,

Edit Microsoft has released a fix for this problem contact support for this

As all of you know the Image class in Dynamics Ax 4.0 and 2009 can only run on client. This poses a problem when you want to print for example invoices with your company logo on it. Having this found out I went to look for an alternative!

I’ve added this code to the top of the PDFViewer class in the writeBitmap(OutputBitmapField _field, OuputSection _section) method

if( isRunningOnServer() &&
    _field.name()       == #FieldLogo)
{
    this.BLOGWriteBitmapOnServer(_field,_section);
    super(_field, _section);
    return;
}

For the method BLOGWriteBitmapOnServer(OutputBitmapField _field, OuputSection _section) I have copied everything from the writeBitmap and started by replacing the Image object with a System.Drawing.Image object, you can make a company parameter for this file path.

img = System.Drawing.Image::FromFile(imgStr);

After compiling there are a few errors witch I’ve corrected and ended up with this code.

public void BLOGWriteBitmapOnServer(OutputBitmapField _field, OuputSection _section)
{
    #File
    BinData bin = new BinData();
    //Image img;
    container data, imgInfoData;
    str s;
    real x1,x2, y1,y2;
    Struct br;
    int imageObjectNo = 0;
    int newwidth, newheight;
    real pdfPreviewScale = 0.8;
    boolean generateXImage = false;
    container c;
    str fn;
    FileIOPermission writePermission;
    FileIOPermission readPermission;
    boolean grayScale = false;
 
    System.Drawing.Image    img;
    str                     imgStr;
    int                     widthTemp, heightTemp;
    CompanyInfo             companyInfo = companyInfo::find();
    ;
 
    new InteropPermission(InteropKind::ClrInterop).assert();
 
    imgStr  = companyInfo.BLOGCompanyLogoFile;
 
    br = this.boundingRectTwips(currentPage, _section, _field);
 
    x1 = br.value('x1'); y1 = br.value('y1');
    x2 = br.value('x2'); y2 = br.value('y2');
 
    if (_field.type() == 10) // resourceId, DB_RESId
    {
        //img = new Image(_field.resourceId());
        img = System.Drawing.Image::FromFile(imgStr);
 
        if (resourceIdImageMap.exists(_field.resourceId()))
            imageObjectNo = resourceIdImageMap.lookup(_field.resourceId());
        else
        {
            imageObjectNo = this.nextObjectNo();
            resourceIdImageMap.insert(_field.resourceId(), imageObjectNo);
            generateXImage = true;
        }
 
        if (debugLevel >= 1)
            info ('Image in resource ' + int2str(_field.resourceId()));
    }
    else if (_field.type() == 7) // queue
    {
        c = _field.value();
        if (c)
        {
            //img = new Image(c);
            img = System.Drawing.Image::FromFile(imgStr);
 
            imageObjectNo = this.nextObjectNo();
        }
        generateXImage = true;
 
        if (debugLevel >= 1)
        {
            if (img)
                info ('Image in container');
            else
                info ('No image in container');
        }
    }
    else // string containing filename
    {
        //img = new Image(_field.imageFileName());
        img = System.Drawing.Image::FromFile(imgStr);
 
        if (stringImageMap.exists(_field.imageFileName()))
            imageObjectNo = stringImageMap.lookup(_field.imageFileName());
        else
        {
            imageObjectNo = this.nextObjectNo();
            stringImageMap.insert(_field.imageFileName(), imageObjectNo);
            generateXImage = true;
        }
 
        if (debugLevel >= 1)
            info ('File is ' + _field.imageFileName());
    }
 
    if (img)
    {
        if (generateXImage)
        {
            fn  = System.IO.Path::GetTempFileName();
 
            widthTemp   = img.get_Width();
            heightTemp  = img.get_Height();
 
            img.Save(fn);
 
            // revert previous assertion
            CodeAccessPermission::revertAssert();
 
            // assert read permissions
            readPermission = new FileIOPermission(fn, #io_read);
            readPermission.assert();
 
            // BP deviation documented (note that the file io assert IS included above)
            bin.loadFile(fn);
            data = bin.getData();
 
            // Get rid of the temporary file.
            //WinAPIServer::deleteFile(fn);
 
            CodeAccessPermission::revertAssert();
            new InteropPermission(InteropKind::ClrInterop).assert();
            System.IO.File::Delete(fn);
 
            if (bitmapEncode85)
                s = bin.ascii85Encode();
            else
                s = BinData::dataToString(data);
 
            objectOffsetMap.insert(imageObjectNo, binBuffer.size());
 
            this.appendTextToBuffer(int2str(imageObjectNo) + ' 0 obj '

This could probably been done much cleaner, but it does the job. 🙂

Dynamics Ax Reports with Calibri font

Hi,

A customer of mine asked me to change the font of some reports to Calibri. It all went well until we saved a report as PDF, there was way too much spacing between characters.

After some days of investigating and contact with Microsoft I’ve found out that it worked on a Windows Server 2008 R2 and the Calibri font files were almost double in size. So I replaced the font files with the ones from Windows Server 2008 R2 and the reports are working like a charm. 🙂