void U_EMRSTRETCHDIBITS_draw(const char *contents, FILE *out, drawingStates *states) { FLAG_PARTIAL; if (states->verbose) { U_EMRSTRETCHDIBITS_print(contents, states); } PU_EMRSTRETCHDIBITS pEmr = (PU_EMRSTRETCHDIBITS)(contents); // check that the header is not outside of the emf file returnOutOfEmf(contents + pEmr->offBmiSrc); returnOutOfEmf(contents + pEmr->offBmiSrc + sizeof(U_BITMAPINFOHEADER)); // get the header PU_BITMAPINFOHEADER BmiSrc = (PU_BITMAPINFOHEADER)(contents + pEmr->offBmiSrc); // check that the bitmap is not outside the emf file returnOutOfEmf(contents + pEmr->offBitsSrc); returnOutOfEmf(contents + pEmr->offBitsSrc + pEmr->cbBitsSrc); const unsigned char *BmpSrc = (const unsigned char *)(contents + pEmr->offBitsSrc); POINT_D size = point_cal(states, (double)pEmr->cDest.x, (double)pEmr->cDest.y); POINT_D position = point_cal(states, (double)pEmr->Dest.x, (double)pEmr->Dest.y); fprintf(out, "<image width=\"%.4f\" height=\"%.4f\" x=\"%.4f\" y=\"%.4f\" ", size.x, size.y, position.x, position.y); clipset_draw(states, out); dib_img_writer(contents, out, states, BmiSrc, BmpSrc, (size_t)pEmr->cbBitsSrc, false); fprintf(out, "/>\n"); }
void U_EMRCREATEMONOBRUSH_draw(const char *contents, FILE *out, drawingStates *states) { PU_EMRCREATEMONOBRUSH pEmr = (PU_EMRCREATEMONOBRUSH)(contents); // check that the header is not outside of the emf file returnOutOfEmf(contents + pEmr->offBmi); returnOutOfEmf(contents + pEmr->offBmi + sizeof(U_BITMAPINFOHEADER)); // get the header PU_BITMAPINFOHEADER BmiSrc = (PU_BITMAPINFOHEADER)(contents + pEmr->offBmi); // check that the bitmap is not outside the emf file returnOutOfEmf(contents + pEmr->offBits); returnOutOfEmf(contents + pEmr->offBits + pEmr->cbBits); const unsigned char *BmpSrc = (const unsigned char *)(contents + pEmr->offBits); emfImageLibrary *image = image_library_writer(contents, out, states, BmiSrc, pEmr->cbBits, BmpSrc); if (image) { // draw image; uint16_t index = pEmr->ihBrush; returnOutOfOTIndex(index); states->objectTable[index].fill_idx = image->id; states->objectTable[index].fill_red = states->currentDeviceContext.fill_red; states->objectTable[index].fill_green = states->currentDeviceContext.fill_green; states->objectTable[index].fill_blue = states->currentDeviceContext.fill_blue; states->objectTable[index].fill_mode = U_BS_MONOPATTERN; states->objectTable[index].fill_set = true; } FLAG_SUPPORTED; if (states->verbose) { U_EMRCREATEMONOBRUSH_print(contents, states); } }
void U_EMRHEADER_draw(const char *contents, FILE *out, drawingStates *states) { FLAG_PARTIAL; if (states->verbose) { U_EMRHEADER_print(contents, states); } char *string; int p1len; PU_EMRHEADER pEmr = (PU_EMRHEADER)(contents); if (pEmr->offDescription) { returnOutOfEmf((uint16_t *)((char *)(intptr_t)pEmr + (intptr_t)pEmr->offDescription) + 2 * (intptr_t)pEmr->nDescription); string = U_Utf16leToUtf8((uint16_t *)((char *)pEmr + pEmr->offDescription), pEmr->nDescription, NULL); free(string); p1len = 2 + 2 * wchar16len((uint16_t *)((char *)pEmr + pEmr->offDescription)); returnOutOfEmf((uint16_t *)((char *)(intptr_t)pEmr + (intptr_t)pEmr->offDescription + (intptr_t)p1len) + 2 * (intptr_t)pEmr->nDescription); string = U_Utf16leToUtf8( (uint16_t *)((char *)pEmr + pEmr->offDescription + p1len), pEmr->nDescription, NULL); free(string); } // object table allocation // allocate one more to directly use object indexes (starts at 1 and not 0) states->objectTable = calloc(pEmr->nHandles + 1, sizeof(emfGraphObject)); states->objectTableSize = pEmr->nHandles; double ratioXY = (double)(pEmr->rclBounds.right - pEmr->rclBounds.left) / (double)(pEmr->rclBounds.bottom - pEmr->rclBounds.top); if ((states->imgHeight != 0) && (states->imgWidth != 0)) { double tmpWidth = states->imgHeight * ratioXY; double tmpHeight = states->imgWidth / ratioXY; if (tmpWidth > states->imgWidth) { states->imgHeight = tmpHeight; } else { states->imgWidth = tmpWidth; } } else if (states->imgHeight != 0) { states->imgWidth = states->imgHeight * ratioXY; } else if (states->imgWidth != 0) { states->imgHeight = states->imgWidth / ratioXY; } else { states->imgWidth = (double)abs(pEmr->rclBounds.right - pEmr->rclBounds.left); states->imgHeight = (double)abs(pEmr->rclBounds.bottom - pEmr->rclBounds.top); } // set scaling for original resolution // states->scaling = 1; states->scaling = states->imgWidth / (double)abs(pEmr->rclBounds.right - pEmr->rclBounds.left); // remember reference point of the output DC states->RefX = (double)pEmr->rclBounds.left; states->RefY = (double)pEmr->rclBounds.top; states->pxPerMm = (double)pEmr->szlDevice.cx / (double)pEmr->szlMillimeters.cx; if (states->svgDelimiter) { fprintf( out, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); fprintf(out, "<%ssvg version=\"1.1\" ", states->nameSpaceString); fprintf(out, "xmlns=\"http://www.w3.org/2000/svg\" "); fprintf(out, "xmlns:xlink=\"http://www.w3.org/1999/xlink\" "); if ((states->nameSpace != NULL) && (strlen(states->nameSpace) != 0)) { fprintf(out, "xmlns:%s=\"http://www.w3.org/2000/svg\" ", states->nameSpace); } fprintf(out, "width=\"%.4f\" height=\"%.4f\">\n", states->imgWidth, states->imgHeight); } fprintf(out, "<%sg transform=\"translate(%.4f, %.4f)\">\n", states->nameSpaceString, -1.0 * states->RefX * states->scaling, -1.0 * states->RefY * states->scaling); }
void U_EMRBITBLT_draw(const char *contents, FILE *out, drawingStates *states) { FLAG_PARTIAL; if (states->verbose) { U_EMRBITBLT_print(contents, states); } PU_EMRBITBLT pEmr = (PU_EMRBITBLT)(contents); // if no bitmap, check for pattern brush // Should fill the output with the current brush and the raster operation if (pEmr->cbBitsSrc == 0) { char style[256]; if (pEmr->dwRop == U_NOOP) return; if (states->currentDeviceContext.fill_mode == U_BS_MONOPATTERN) { sprintf(style, "fill:url(#img-%d-ref);", states->currentDeviceContext.fill_idx); } else if (states->currentDeviceContext.fill_mode == U_BS_SOLID) { sprintf(style, "fill:#%02x%02x%02x", states->currentDeviceContext.fill_red, states->currentDeviceContext.fill_green, states->currentDeviceContext.fill_blue); } else { style[0] = '\0'; } if (style[0]) { POINT_D size = point_cal(states, (double)pEmr->cDest.x, (double)pEmr->cDest.y); POINT_D position = point_cal(states, (double)pEmr->Dest.x, (double)pEmr->Dest.y); fprintf(out, "<%spath style=\"%s", states->nameSpaceString, style); fprintf( out, "\" d=\"M %.4f,%.4f L %.4f,%.4f L %.4f,%.4f L %.4f,%.4f Z\" />", position.x, position.y, position.x + size.x, position.y, position.x + size.x, position.y + size.y, position.x, position.y + size.y); } // else // FIXME - non MONOBRUSH return; } // FIXME doesn't handle ternary raster operation // check that the header is not outside of the emf file returnOutOfEmf(contents + pEmr->offBmiSrc); returnOutOfEmf(contents + pEmr->offBmiSrc + sizeof(U_BITMAPINFOHEADER)); // get the header PU_BITMAPINFOHEADER BmiSrc = (PU_BITMAPINFOHEADER)(contents + pEmr->offBmiSrc); // check that the bitmap is not outside the emf file returnOutOfEmf(contents + pEmr->offBitsSrc); returnOutOfEmf(contents + pEmr->offBitsSrc + pEmr->cbBitsSrc); const unsigned char *BmpSrc = (const unsigned char *)(contents + pEmr->offBitsSrc); POINT_D size = point_cal(states, (double)pEmr->cDest.x, (double)pEmr->cDest.y); POINT_D position = point_cal(states, (double)pEmr->Dest.x, (double)pEmr->Dest.y); fprintf(out, "<image width=\"%.4f\" height=\"%.4f\" x=\"%.4f\" y=\"%.4f\" ", size.x, size.y, position.x, position.y); clipset_draw(states, out); // float alpha = (float)pEmr->Blend.Global / 255.0; // fprintf(out, " fill-opacity=\"%.4f\" ", alpha); dib_img_writer(contents, out, states, BmiSrc, BmpSrc, (size_t)pEmr->cbBitsSrc, false); fprintf(out, "/>\n"); }