/*
 * Class:     org_libharu_PdfPage
 * Method:    clip
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_org_libharu_PdfPage_clip(JNIEnv *env, jobject obj) {
    jint page;
    /* Get mHPDFPagePointer */
    page = (*env)->GetIntField(env, obj, mHPDFPagePointer);
    HPDF_Page_Clip((HPDF_Page) page);
}
Esempio n. 2
0
void WPdfImage::drawImage(const WRectF& rect, const std::string& imgUrl,
			  int imgWidth, int imgHeight,
			  const WRectF& srect)
{
  HPDF_Image img = 0;

  if (Uri::isDataUri(imgUrl)) {
    Uri::Uri uri = Uri::parseDataUri(imgUrl);
    if ("image/png" == uri.mimeType)
      img = HPDF_LoadPngImageFromMem(pdf_, 
				     (HPDF_BYTE*)uri.data.c_str(), 
				     uri.data.size()); 
    else if ("image/jpeg" == uri.mimeType)
      img = HPDF_LoadJpegImageFromMem(pdf_, 
				      (HPDF_BYTE*)uri.data.c_str(), 
				      uri.data.size()); 
  } else {
    std::string mimeType = Image::identifyImageFileMimeType(imgUrl);
    if ("image/png" == mimeType)
      img = HPDF_LoadPngImageFromFile2(pdf_, imgUrl.c_str());
    else if ("image/jpeg" == mimeType)
      img = HPDF_LoadJpegImageFromFile(pdf_, imgUrl.c_str());
  } 

  if (!img)
    throw WException("WPdfImage::drawImage(): cannot load image: " + imgUrl);

  double x = rect.x();
  double y = rect.y();
  double width = rect.width();
  double height = rect.height();

  HPDF_Page_GSave(page_);

  if (srect.x() != 0
      || srect.y() != 0
      || srect.width() != imgWidth
      || srect.height() != imgHeight) {
    double scaleX = width / imgWidth;
    double scaleY = height / imgHeight;

    x -= srect.x() * scaleX;
    y -= srect.y() * scaleY;
    width *= scaleX;
    height *= scaleY;

    HPDF_Page_Rectangle(page_, rect.x(), rect.y(), rect.width(), rect.height());
    HPDF_Page_Clip(page_);
  }

  HPDF_Page_Concat(page_, 1, 0, 0, -1, x, y + height); // revert upside-down

  HPDF_Page_DrawImage(page_, img, 0, 0, width, height);

  HPDF_Page_GRestore(page_);
}
Esempio n. 3
0
/**
 * Enter/leave text mode and update PDF gstate for its clip, fill & stroke
 * colour, line width and dash pattern parameters.
 * \param selectTextMode true if text mode needs to be entered if required;
 * false otherwise.
 * \param fillCol Desired fill colour, use NS_TRANSPARENT if no update is
 * required.
 * \param strokeCol Desired stroke colour, use NS_TRANSPARENT if no update is
 * required.
 * \param lineWidth Desired line width. Only taken into account when strokeCol
 * is different from NS_TRANSPARENT.
 * \param dash Desired dash pattern. Only taken into account when strokeCol
 * is different from NS_TRANSPARENT.
 */
static void apply_clip_and_mode(bool selectTextMode, colour fillCol,
		colour strokeCol, float lineWidth, DashPattern_e dash)
{
	/* Leave text mode when
	 *  1) we're not setting text anymore
	 *  2) or we need to update the current clippath
	 *  3) or we need to update any fill/stroke colour, linewidth or dash.
	 * Note: the test on stroke parameters (stroke colour, line width and
	 * dash) is commented out as if these need updating we want to be
	 * outside the text mode anyway (i.e. selectTextMode is false).
	 */
	if (in_text_mode && (!selectTextMode || clip_update_needed
		|| (fillCol != NS_TRANSPARENT
			&& fillCol != pdfw_gs[pdfw_gs_level].fillColour)
		/* || (strokeCol != NS_TRANSPARENT
			&& (strokeCol != pdfw_gs[pdfw_gs_level].strokeColour
				|| lineWidth != pdfw_gs[pdfw_gs_level].lineWidth
				|| dash != pdfw_gs[pdfw_gs_level].dash)) */)) {
		HPDF_Page_EndText(pdf_page);
		in_text_mode = false;
	}

	if (clip_update_needed)
		pdfw_gs_restore(pdf_page);

	/* Update fill/stroke colour, linewidth and dash when needed.  */
	if (fillCol != NS_TRANSPARENT)
		pdfw_gs_fillcolour(pdf_page, fillCol);
	if (strokeCol != NS_TRANSPARENT) {
		pdfw_gs_strokecolour(pdf_page, strokeCol);
		pdfw_gs_linewidth(pdf_page, lineWidth);
		pdfw_gs_dash(pdf_page, dash);
	}

	if (clip_update_needed) {
		pdfw_gs_save(pdf_page);

		HPDF_Page_Rectangle(pdf_page, last_clip_x0,
				page_height - last_clip_y1,
				last_clip_x1 - last_clip_x0,
				last_clip_y1 - last_clip_y0);
		HPDF_Page_Clip(pdf_page);
		HPDF_Page_EndPath(pdf_page);

		clip_update_needed = false;
	}

	if (selectTextMode && !in_text_mode) {
		HPDF_Page_BeginText(pdf_page);
		in_text_mode = true;
	}
}
Esempio n. 4
0
void WPdfImage::drawImage(const WRectF& rect, const std::string& imgUrl,
			  int imgWidth, int imgHeight,
			  const WRectF& srect)
{
  HPDF_Image img = nullptr;

  if (DataUri::isDataUri(imgUrl)) {
#define HAVE_LOAD_FROM_MEM HPDF_MAJOR_VERSION > 2 || (HPDF_MAJOR_VERSION == 2 && (HPDF_MINOR_VERSION >= 2))

#if HAVE_LOAD_FROM_MEM
    DataUri uri(imgUrl);
    if ("image/png" == uri.mimeType)
      img = HPDF_LoadPngImageFromMem(pdf_, 
				     (HPDF_BYTE*)&uri.data[0], 
				     uri.data.size()); 
    else if ("image/jpeg" == uri.mimeType)
      img = HPDF_LoadJpegImageFromMem(pdf_, 
				      (HPDF_BYTE*)&uri.data[0], 
				      uri.data.size());
#else
      LOG_ERROR("drawImage: data URI support requires libharu 2.2.0 or later");
#endif
  } else {
    std::string mimeType = ImageUtils::identifyMimeType(imgUrl);
    if ("image/png" == mimeType)
      img = HPDF_LoadPngImageFromFile2(pdf_, imgUrl.c_str());
    else if ("image/jpeg" == mimeType)
      img = HPDF_LoadJpegImageFromFile(pdf_, imgUrl.c_str());
  } 

  if (!img)
    throw WException("WPdfImage::drawImage(): cannot load image: " + imgUrl);

  double x = rect.x();
  double y = rect.y();
  double width = rect.width();
  double height = rect.height();

  HPDF_Page_GSave(page_);

  if (srect.x() != 0
      || srect.y() != 0
      || srect.width() != imgWidth
      || srect.height() != imgHeight) {
    double scaleX = width / imgWidth;
    double scaleY = height / imgHeight;

    x -= srect.x() * scaleX;
    y -= srect.y() * scaleY;
    width *= scaleX;
    height *= scaleY;

    HPDF_Page_Rectangle(page_, rect.x(), rect.y(), rect.width(), rect.height());
    HPDF_Page_Clip(page_);
  }

  HPDF_Page_Concat(page_, 1, 0, 0, -1, x, y + height); // revert upside-down

  HPDF_Page_DrawImage(page_, img, 0, 0, width, height);

  HPDF_Page_GRestore(page_);
}
Esempio n. 5
0
void WPdfImage::setChanged(WFlags<PainterChangeFlag> flags)
{
  if (!flags.empty()) {
    HPDF_Page_GRestore(page_);
    HPDF_Page_GSave(page_);

    HPDF_ExtGState gstate;
    gstate = HPDF_CreateExtGState (pdf_);

    currentFont_ = WFont();

    if (painter()->hasClipping()) {
      const WTransform& t = painter()->clipPathTransform();

      if (!painter()->clipPath().isEmpty()) {
        applyTransform(t);

        drawPlainPath(painter()->clipPath());
        HPDF_Page_Clip(page_);
        HPDF_Page_EndPath(page_);

        applyTransform(t.inverted());
      }
    }

    applyTransform(painter()->combinedTransform());

    const WPen& pen = painter()->pen();

    if (pen.style() != PenStyle::None) {
      const WColor& color = pen.color();

      HPDF_Page_SetRGBStroke(page_,
                             color.red() / 255.,
                             color.green() / 255.,
                             color.blue() / 255.);

      HPDF_ExtGState_SetAlphaStroke (gstate, color.alpha()/255.);

      WLength w = painter()->normalizedPenWidth(pen.width(), false);
      HPDF_Page_SetLineWidth(page_, w.toPixels());

      switch (pen.capStyle()) {
      case PenCapStyle::Flat:
	HPDF_Page_SetLineCap(page_, HPDF_BUTT_END);
	break;
      case PenCapStyle::Square:
	HPDF_Page_SetLineCap(page_, HPDF_PROJECTING_SCUARE_END); // scuary !
	break;
      case PenCapStyle::Round:
	HPDF_Page_SetLineCap(page_, HPDF_ROUND_END);
	break;
      }

      switch (pen.joinStyle()) {
      case PenJoinStyle::Miter:
	HPDF_Page_SetLineJoin(page_, HPDF_MITER_JOIN);
	break;
      case PenJoinStyle::Bevel:
	HPDF_Page_SetLineJoin(page_, HPDF_BEVEL_JOIN);
	break;
      case PenJoinStyle::Round:
	HPDF_Page_SetLineJoin(page_, HPDF_ROUND_JOIN);
	break;
      }

      switch (pen.style()) {
      case PenStyle::None:
	break;
      case PenStyle::SolidLine:
	HPDF_Page_SetDash(page_, nullptr, 0, 0);
	break;
      case PenStyle::DashLine: {
	const HPDF_UINT16 dash_ptn[] = { 4, 2 };
	HPDF_Page_SetDash(page_, dash_ptn, 2, 0);
	break;
      }
      case PenStyle::DotLine: {
	const HPDF_UINT16 dash_ptn[] = { 1, 2 };
	HPDF_Page_SetDash(page_, dash_ptn, 2, 0);
	break;
      }
      case PenStyle::DashDotLine: {
	const HPDF_UINT16 dash_ptn[] = { 4, 2, 1, 2 };
	HPDF_Page_SetDash(page_, dash_ptn, 4, 0);
	break;
      }
      case PenStyle::DashDotDotLine: {
	const HPDF_UINT16 dash_ptn[] = { 4, 2, 1, 2, 1, 2 };
	HPDF_Page_SetDash(page_, dash_ptn, 6, 0);
	break;
      }
      }
    }

    const WBrush& brush = painter()->brush();

    if (brush.style() != BrushStyle::None) {
      const WColor& color = painter()->brush().color();

      HPDF_Page_SetRGBFill(page_,
                           color.red() / 255.,
                           color.green() / 255.,
                           color.blue() / 255.);

      HPDF_ExtGState_SetAlphaFill (gstate, color.alpha()/255.);
    }

    HPDF_Page_SetExtGState (page_, gstate);

    

    const WFont& font = painter()->font();

    if (font == currentFont_ && !trueTypeFonts_->busy())
      return;

    /*
     * First, try a true type font.
     */
    std::string ttfFont;
    if (trueTypeFonts_->busy()) {
      /*
       * We have a resolved true type font.
       */
      ttfFont = trueTypeFonts_->drawingFontPath();
    } else {
      FontSupport::FontMatch match = trueTypeFonts_->matchFont(font);

      if (match.matched())
	ttfFont = match.fileName();
    }

    LOG_DEBUG("font: " << ttfFont);

    if (font == currentFont_ &&
        !ttfFont.empty() &&
        currentTtfFont_ == ttfFont)
      return;

    currentFont_ = font;

    const char *font_name = nullptr;
    font_ = nullptr;

    if (!ttfFont.empty()) {

      bool fontOk = false;

      std::map<std::string, const char *>::const_iterator i
	= ttfFonts_.find(ttfFont);

      if (i != ttfFonts_.end()) {
	font_name = i->second;
	fontOk = true;
      } else if (ttfFont.length() > 4) {
	std::string suffix
	  = Utils::lowerCase(ttfFont.substr(ttfFont.length() - 4));

	if (suffix == ".ttf") {
	  font_name = HPDF_LoadTTFontFromFile (pdf_, ttfFont.c_str(),
					       HPDF_TRUE);
	} else if (suffix == ".ttc") {
	  /* Oops, pango didn't tell us which font to load ... */
	  font_name = HPDF_LoadTTFontFromFile2(pdf_, ttfFont.c_str(),
					       0, HPDF_TRUE);
	}

	if (!font_name)
	  HPDF_ResetError (pdf_);
	else {
	  ttfFonts_[ttfFont] = font_name;
	  fontOk = true;
	}
      }

      if (!fontOk)
	LOG_ERROR("cannot read font: '" << ttfFont << "': "
		  "expecting a true type font (.ttf, .ttc)");
    }

    if (!font_ && font_name) {
      font_ = HPDF_GetFont (pdf_, font_name, "UTF-8");

      if (!font_)
	HPDF_ResetError (pdf_);
      else {
	trueTypeFont_ = true;
        currentTtfFont_ = ttfFont;
      }
    }

    if (!font_) {
      trueTypeFont_ = false;
      currentTtfFont_.clear();

      std::string name = Pdf::toBase14Font(font);
      font_ = HPDF_GetFont(pdf_, name.c_str(), nullptr);
    }

    fontSize_ = font.sizeLength(12).toPixels();

    HPDF_Page_SetFontAndSize (page_, font_, fontSize_);
  }
}