Esempio n. 1
0
void 
GBitmap::init(const GBitmap &ref, const GRect &rect, int border)
{
  GMonitorLock lock(monitor());
  // test bitmap physical equality
  if (this == &ref)
    {
      GBitmap tmp;
      tmp.grays = grays;
      tmp.border = border;
      tmp.bytes_per_row = bytes_per_row;
      tmp.ncolumns = ncolumns;
      tmp.nrows = nrows;
      tmp.bytes = bytes;
      tmp.gbytes_data.swap(gbytes_data);
      tmp.grle.swap(grle);
      bytes = 0 ;
      init(tmp, rect, border);
    }
  else
    {
      GMonitorLock lock(ref.monitor());
      // create empty bitmap
      init(rect.height(), rect.width(), border);
      grays = ref.grays;
      // compute destination rectangle
      GRect rect2(0, 0, ref.columns(), ref.rows() );
      rect2.intersect(rect2, rect);
      rect2.translate(-rect.xmin, -rect.ymin);
      // copy bits
      if (! rect2.isempty())
        {
          for (int y=rect2.ymin; y<rect2.ymax; y++)
            {
              unsigned char *dst = (*this)[y];
              const unsigned char *src = ref[y+rect.ymin] + rect.xmin;
              for (int x=rect2.xmin; x<rect2.xmax; x++)
                dst[x] = src[x];
            }
        }
    }
}
Esempio n. 2
0
GP<GBitmap>
JB2Image::get_bitmap(const GRect &rect, int subsample, int align, int dispy) const
{
  if (width==0 || height==0)
    G_THROW( ERR_MSG("JB2Image.cant_create") );
  int rxmin = rect.xmin * subsample;
  int rymin = rect.ymin * subsample;
  int swidth = rect.width();
  int sheight = rect.height();
  int border = ((swidth + align - 1) & ~(align - 1)) - swidth;
  GP<GBitmap> bm = GBitmap::create(sheight, swidth, border);
  bm->set_grays(1+subsample*subsample);
  for (int blitno = 0; blitno < get_blit_count(); blitno++)
    {
      const JB2Blit *pblit = get_blit(blitno);
      const JB2Shape  &pshape = get_shape(pblit->shapeno);
      if (pshape.bits)
        bm->blit(pshape.bits, pblit->left-rxmin, pblit->bottom-rymin+dispy, subsample);
    }
  return bm;
}
void
MapArea::draw(const GRect & bm_rect, const GP<GBitmap> & bm_in,
	      GRect & pm_rect, GP<GPixmap> & pm_out,
	      DRAW_MODE draw_mode)
      // Draws itself into the specified bitmap. The bm_rect should be
      // in the pane's coordinates. Since GBitmap may not contain color
      // information, we will create a color GPixmap patch (pm_out), where we
      // will actually be drawing. The pm_rect is a rectangle in
      // pane coordinates where this pm_out should go to.
{
   DEBUG_MSG("MapArea::draw(): Highlighting " << gmap_area->url << ":" <<
	     gmap_area->target << "\n");
   DEBUG_MAKE_INDENT(3);

   if (pane)
   {
      GRect brect=gmap_area->get_bound_rect();
      mapper->map(brect);
      brect.inflate(3, 3);
      
      GRect irect;
      if (irect.intersect(bm_rect, brect))
      {
	 pm_rect=irect;
	 irect.translate(-bm_rect.xmin, -bm_rect.ymin);
	 pm_out=GPixmap::create(*bm_in, GRect(irect.xmin, bm_in->rows()-irect.ymax,
					  irect.width(), irect.height()));
	 if (!isInactiveOutlineMode())
	    if (draw_mode==DRAW_INACTIVE || draw_mode==DRAW_ACTIVE)
	       ma_drawInactive(pm_rect, pm_out);
	 if (!isActiveOutlineMode())
	    if (draw_mode==APPLY_ACTIVE || draw_mode==DRAW_ACTIVE)
	       ma_applyActive(pm_rect, pm_out);
      }
   }
}
PrintingPathContur::PrintingPathContur(Path *sourcePath, double boardXSize, double boardYSize, double nozzleDiameter)
    :PathContur(boardXSize, boardYSize, nozzleDiameter), mLast(0)
{
    mWarnings = 0;
    if(sourcePath==0)
        return;

    Path *nextPath = sourcePath;
    while(nextPath) {
        GShape *next = nextPath->firstElement;
        while(next) {
            switch(next->type()) {
                case GSHAPE_LINE:
                {
                    GLine *line = (GLine*)next;
                    if(fabs(line->width-nozzleDiameter)<0.0001L) {
                        addShape(new GLine(line->p1, line->p2, nozzleDiameter, true));
                    } else if(line->width>nozzleDiameter) {
                        GPoint a = line->p2 - line->p1;
                        a.vectorNormalize();
                        GPoint o = GPoint(a.y, -a.x);
                        o *= nozzleDiameter;

                        int c = line->width/2.0L/nozzleDiameter+1.0L;
                        const double edge = (line->width-nozzleDiameter)/2.0L;
                        for(int i=0; i<=c; i++) {
                            GPoint s = a*edgeDelta(nozzleDiameter, line->width, o*i);
                            if((o*i).vectorLength()<=edge) {
                                addShape(new GLine(line->p1+o*i-s, line->p2+o*i+s, nozzleDiameter, true));
                                if(i!=0)
                                    addShape(new GLine(line->p1-o*i-s, line->p2-o*i+s, nozzleDiameter, true));
                            } else {
                                o.vectorNormalize();
                                GPoint s = a*edgeDelta(nozzleDiameter, line->width, o*edge);
                                addShape(new GLine(line->p1+o*edge-s, line->p2+o*edge+s, nozzleDiameter, true));
                                addShape(new GLine(line->p1-o*edge-s, line->p2-o*edge+s, nozzleDiameter, true));
                                break;
                            }
                        }
                    } else {
                        mWarnings = ERROR_DIAMETER;
                    }
                    break;
                }
                case GSHAPE_CIRCLE:
                {
                    GCircle *circle = (GCircle*)next;
                    if(circle->radius >= nozzleDiameter) {
                        int c = circle->radius/nozzleDiameter;
                        for(int i=0; i<=c; i++) {
                            double r = circle->radius - nozzleDiameter/2.0L - i*nozzleDiameter;
                            if(r >= nozzleDiameter/2.0L) {
                                GCircle *result = new GCircle(circle->center, r, nozzleDiameter);
                                result->outer = i==0;
                                addShape(result);
                            } else {
                                GCircle *result = new GCircle(circle->center, nozzleDiameter/2.0L, nozzleDiameter);
                                result->outer = i==0;
                                addShape(result);
                                break;
                            }
                        }
                    } else {
                        mWarnings = ERROR_DIAMETER;
                    }
                    break;
                }
                case GSHAPE_RECT:
                {
                    GRect *rect = (GRect*)next;
                    if(rect->width()>=nozzleDiameter && rect->height()>=nozzleDiameter) {
                        int c = rect->height()/nozzleDiameter;
                        GPoint pl(rect->topLeft.x+nozzleDiameter/2.0L, rect->bottomRight.y);
                        GPoint pr(rect->bottomRight.x-nozzleDiameter/2.0L,rect->bottomRight.y);
                        double y =pl.y;
                        for(int i=0; i<=c; i++) {
                           pr.y = pl.y = y + nozzleDiameter*i+nozzleDiameter/2.0L;
                           if(pr.y<rect->topLeft.y-nozzleDiameter/2.0L) {
                                addShape(new GLine(pl, pr, nozzleDiameter, true));
                           } else {
                               pr.y = pl.y = rect->topLeft.y-nozzleDiameter/2.0L;
                               addShape(new GLine(pl, pr, nozzleDiameter, true));
                               break;
                           }
                        }
                        addShape(new GLine(GPoint(rect->topLeft.x+nozzleDiameter/2.0L, rect->topLeft.y-nozzleDiameter/2.0L), \
                                            GPoint(rect->topLeft.x+nozzleDiameter/2.0L, rect->bottomRight.y+nozzleDiameter/2.0L), nozzleDiameter, true));
                        addShape(new GLine(GPoint(rect->bottomRight.x-nozzleDiameter/2.0L, rect->topLeft.y-nozzleDiameter/2.0L), \
                                            GPoint(rect->bottomRight.x-nozzleDiameter/2.0L, rect->bottomRight.y+nozzleDiameter/2.0L), nozzleDiameter, true));
                    } else {
                        mWarnings = ERROR_DIAMETER;
                    }
                    break;
                }
            }

            next = next->next;
        }
        nextPath = nextPath->next;
    }
}
void
MapRect::makeFrame(const GRect & mod_rect,
		   GPixmap * pm,
		   const GRect & pm_rect,
		   int top_margin, int right_margin,
		   int bottom_margin, int left_margin)
      // pm_rect is the place in pane coordinates where pm is supposed
      // to go. mod_rect is the place in pane coordinates, which should
      // be modified (all or part of it)
      // margins define distances from mod_rect's sides to the sides of
      // the rectangular map area. If they're positive, it means, that
      // mod_rect is completely inside the map area. Otherwise part of
      // it is outside
{
   int dst_x, dst_y;
      // TOP
   for(dst_y=mod_rect.height()-1;dst_y>mod_rect.height()-1-(gmap_area->border_width-top_margin) && dst_y>=0;dst_y--)
   {
      int distance=(mod_rect.height()-1-dst_y)+top_margin;
      int left=-left_margin+distance;
      int right=mod_rect.width()+right_margin-distance;
      if (left<0) left=0;
      if (right>mod_rect.width()) right=mod_rect.width();
      for(dst_x=left;dst_x<right;dst_x++)
      {
	 GPixel & pix=(*pm)[dst_y+pm_rect.ymax-mod_rect.ymax]
			   [dst_x+mod_rect.xmin-pm_rect.xmin];
	 int inc=shadow_pattern[distance];
	 if (inc>0)
	 {
	    pix.r=pix.r<=255-inc ? pix.r+inc : 255;
	    pix.g=pix.g<=255-inc ? pix.g+inc : 255;
	    pix.b=pix.b<=255-inc ? pix.b+inc : 255;
	 } else
	 {
	    pix.r=pix.r>=-inc ? pix.r+inc : 0;
	    pix.g=pix.g>=-inc ? pix.g+inc : 0;
	    pix.b=pix.b>=-inc ? pix.b+inc : 0;
	 }
      }
   }
      // RIGHT
   for(dst_x=mod_rect.width()-1;dst_x>mod_rect.width()-1-(gmap_area->border_width-right_margin) && dst_x>=0;dst_x--)
   {
      int distance=(mod_rect.width()-1-dst_x)+right_margin;
      int bottom=-bottom_margin+distance;
      int top=mod_rect.height()+top_margin-distance;
      if (bottom<0) bottom=0;
      if (top>mod_rect.height()) top=mod_rect.height();
      for(dst_y=bottom;dst_y<top;dst_y++)
      {
	 GPixel & pix=(*pm)[dst_y+pm_rect.ymax-mod_rect.ymax]
			   [dst_x+mod_rect.xmin-pm_rect.xmin];
	 int inc=-shadow_pattern[distance];
	 if (inc>0)
	 {
	    pix.r=pix.r<=255-inc ? pix.r+inc : 255;
	    pix.g=pix.g<=255-inc ? pix.g+inc : 255;
	    pix.b=pix.b<=255-inc ? pix.b+inc : 255;
	 } else
	 {
	    pix.r=pix.r>=-inc ? pix.r+inc : 0;
	    pix.g=pix.g>=-inc ? pix.g+inc : 0;
	    pix.b=pix.b>=-inc ? pix.b+inc : 0;
	 }
      }
   }
      // BOTTOM
   for(dst_y=0;dst_y<gmap_area->border_width-bottom_margin && dst_y<mod_rect.height();dst_y++)
   {
      int distance=dst_y+bottom_margin;
      int left=-left_margin+distance;
      int right=mod_rect.width()+right_margin-distance;
      if (left<0) left=0;
      if (right>mod_rect.width()) right=mod_rect.width();
      for(dst_x=left;dst_x<right;dst_x++)
      {
	 GPixel & pix=(*pm)[dst_y+pm_rect.ymax-mod_rect.ymax]
			   [dst_x+mod_rect.xmin-pm_rect.xmin];
	 int inc=-shadow_pattern[distance];
	 if (inc>0)
	 {
	    pix.r=pix.r<=255-inc ? pix.r+inc : 255;
	    pix.g=pix.g<=255-inc ? pix.g+inc : 255;
	    pix.b=pix.b<=255-inc ? pix.b+inc : 255;
	 } else
	 {
	    pix.r=pix.r>=-inc ? pix.r+inc : 0;
	    pix.g=pix.g>=-inc ? pix.g+inc : 0;
	    pix.b=pix.b>=-inc ? pix.b+inc : 0;
	 }
      }
   }
      // LEFT
   for(dst_x=0;dst_x<gmap_area->border_width-left_margin && dst_x<mod_rect.width();dst_x++)
   {
      int distance=dst_x+left_margin;
      int bottom=-bottom_margin+distance;
      int top=mod_rect.height()+top_margin-distance;
      if (bottom<0) bottom=0;
      if (top>mod_rect.height()) top=mod_rect.height();
      for(dst_y=bottom;dst_y<top;dst_y++)
      {
	 GPixel & pix=(*pm)[dst_y+pm_rect.ymax-mod_rect.ymax]
			   [dst_x+mod_rect.xmin-pm_rect.xmin];
	 int inc=shadow_pattern[distance];
	 if (inc>0)
	 {
	    pix.r=pix.r<=255-inc ? pix.r+inc : 255;
	    pix.g=pix.g<=255-inc ? pix.g+inc : 255;
	    pix.b=pix.b<=255-inc ? pix.b+inc : 255;
	 } else
	 {
	    pix.r=pix.r>=-inc ? pix.r+inc : 0;
	    pix.g=pix.g>=-inc ? pix.g+inc : 0;
	    pix.b=pix.b>=-inc ? pix.b+inc : 0;
	 }
      }
   }
}
void
MapArea::updateCache(const GRect & pm_rect, const GP<GPixmap> & pm,
		     GRectMapper * sdoc_mapper)
      // Takes the passed pixmap and updated the internal cache.
      // The pixmap should already contain the hyperlink draw in the
      // INACTIVE state. We will copy it and apply ACTIVE part here.
      // pm_rect is a rectangle in pane's coordinates where pm is supposed
      // to go to. sdoc_mapper maps screen coordinates to the coordinates
      // of the scaled document (see qd_base_paint.cpp)
{
   DEBUG_MSG("MapArea::updateCache(): updating caches\n");
   DEBUG_MAKE_INDENT(3);

   if (!isCacheUsed() || !pm || !pane) return;
   
   GRect brect=gmap_area->get_bound_rect();
   mapper->map(brect);
   brect.inflate(3, 3);		// To take into account edit controls
      
   GRect urect;
   if (urect.intersect(pm_rect, brect))
   {
      for(GPosition pos=pieces;pos;++pos)
      {
	 GP<MapPiece> piece=pieces[pos];
	 GRect prect=*piece;
	 mapper->map(prect);
	 GRect irect;
	 if (irect.intersect(prect, urect))
	 {
	    if (piece->getOnPixmap().isNull() || piece->getOffPixmap().isNull())
	       piece->createPixmaps();

	    QPixmap & on_pix=piece->getOnPixmap();
	    QPixmap & off_pix=piece->getOffPixmap();

	       // Now I need to make a copy of the area to be cached.
	       // The problem is that I'll need to draw into the GPixmap
	       // and I don't want to spoil the original.
	    GP<GPixmap> ipix_off;
	    GRect pix_rect=irect;
	    pix_rect.translate(-pm_rect.xmin, -pm_rect.ymin);
	    ipix_off=GPixmap::create(*pm, GRect(pix_rect.xmin, pm->rows()-pix_rect.ymax,
					    pix_rect.width(), pix_rect.height()));
	    GP<GPixmap> ipix_on=GPixmap::create(*ipix_off);

	       // Now ipix_off and ipix_on contains the data, which can be modified.
	       // Draw the map area into them
	    draw(irect, ipix_on, APPLY_ACTIVE);

	       // Dither pix_off and pix_on
	    GRect drect=irect;
	    sdoc_mapper->map(drect);
	    if (qxImager)
              qxImager->dither(*ipix_on, drect.xmin, drect.ymin);
	    if (qxImager)
              qxImager->dither(*ipix_off, drect.xmin, drect.ymin);

	       // Now copy the GPixmaps into QPixmaps to be used for caching
	    QDPainter p_off(&off_pix);
	    p_off.drawPixmap(GRect(irect.xmin-prect.xmin,
				   irect.ymin-prect.ymin,
				   irect.width(), irect.height()), ipix_off);
	    p_off.end();
	    
	    QDPainter p_on(&on_pix);
	    p_on.drawPixmap(GRect(irect.xmin-prect.xmin,
				  irect.ymin-prect.ymin,
				  irect.width(), irect.height()), ipix_on);
	    p_on.end();
	 }
      }
   }
}
Esempio n. 7
0
	/**
	 *	Scale and translate the bitmap such that is fills the specific rectangle.
	 *
	 *	Any area in the rectangle that is outside of the bounds of the canvas is ignored.
	 *
	 *	If a given pixel in the bitmap is not opaque (e.g. GPixel_GetA() < 255) then blend it
	 *	using SRCOVER blend mode.
	 */
	void fillBitmapRect(const GBitmap& src, const GRect& dst) {
		// Store dimensions of dst rectangle
		int left = dst.left();
		int top = dst.top();
		int right = dst.right();
		int bottom = dst.bottom();
		int rW = dst.width();
		int rH = dst.height();

		// Store dimensions of src bitmap
		int bW = src.width();
		int bH = src.height();

		// Find necessary scale factor for both width and height
		float sx = (float)bW/(float)rW;
		float sy = (float)bH/(float)rH;

		float tx = 0 - left;
		float ty = 0 - top;

		// Create matrix for scaling
		float scale[6] = 
			{sx, 0, 0, 
			 0, sy, 0};

		// Create matrix for translating
		float translate[6] =
			{1, 0, tx,
			 0, 1, ty};

		// Combine the matrices
		float both[6] = 
			{sx, 0, sx*tx,
			 0, sy, sy*ty};

		// For loop that takes each point in dst and find corresponding point in src
		GPixel* d = draw.fPixels;
		d = (GPixel*)((char*)d + (int)top * draw.rowBytes());
		for (int y = top; y < bottom; ++y) {
			for (int x = left; x < right; ++x) {
				// Only map pixels that are in the bitmap
				if ((x >= 0 && x < draw.width()) && (y >= 0 && y < draw.height())) {
					// Find corresponding point in src bitmap
					int xP;
					int yP;

					xP = both[0] * x + both[1] * y + both[2];
					yP = both[3] * x + both[4] * y + both[5];

					// Apply CTM to x and y
					int nX = (CTM[0] * x) + (CTM[1] * y) + (CTM[2]);
					int nY = (CTM[3] * x) + (CTM[4] * y) + (CTM[5]);

					// Prepare color to fill
					unsigned a = GPixel_GetA(*src.getAddr(xP, yP));
					unsigned r = GPixel_GetR(*src.getAddr(xP, yP));
					unsigned g = GPixel_GetG(*src.getAddr(xP, yP));
					unsigned b = GPixel_GetB(*src.getAddr(xP, yP));

					unsigned nA = a;
					unsigned nR = r;
					unsigned nG = g;
					unsigned nB = b;

					if (GPixel_GetA(*draw.getAddr(x, y)) > 0) {
	    	    		// blend
						float lA = GPixel_GetA(*src.getAddr(xP, yP)) / 255.99999;
						float lR = GPixel_GetR(*src.getAddr(xP, yP)) / 255.99999;
						float lG = GPixel_GetG(*src.getAddr(xP, yP)) / 255.99999;
						float lB = GPixel_GetB(*src.getAddr(xP, yP)) / 255.99999;

						
						float sA = lA + ((GPixel_GetA(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA));
						float sR = lR + ((GPixel_GetR(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA));
						float sG = lG + ((GPixel_GetG(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA));
						float sB = lB + ((GPixel_GetB(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA));
						

						/*
						float sA = lA + ((GPixel_GetA(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA));
						float sR = lR + ((GPixel_GetR(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA));
						float sG = lG + ((GPixel_GetG(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA));
						float sB = lB + ((GPixel_GetB(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA));
						*/
										
						nA = (int)(sA * 255.99999);
						nR = (int)(sR * 255.99999);
						nG = (int)(sG * 255.99999);
						nB = (int)(sB * 255.99999);

	    	    		d[x] = GPixel_PackARGB(nA, nR, nG, nB);
	    	    		//d = (GPixel*)((char*)d + (int)nY * draw.rowBytes());
	    	    		//d[nX] = GPixel_PackARGB(nA, nR, nG, nB);
	    	    		//d = (GPixel*)((char*)d - (int)nY * draw.rowBytes());
    	    		} else {
    	    			d[x] = GPixel_PackARGB(a, r, g, b);
    	    			//d = (GPixel*)((char*)d + (int)nY * draw.rowBytes());
	    	    		//d[nX] = GPixel_PackARGB(a, r, g, b);
	    	    		//d = (GPixel*)((char*)d - (int)nY * draw.rowBytes());
    	    		}	    		
				}
			}
			d = (GPixel*)((char*)d + draw.rowBytes());
		}
	}