RRect RLineCache::flush(class IRichCompositor* compositor)
{
	RRect line_rect;

	// no element yet, need not flush!
	element_list_t* line = getCachedElements();
	if ( line->size() == 0 )
		return line_rect;

	// line mark
	std::vector<element_list_t::iterator> line_marks;
	std::vector<short> line_widths;

	RRect zone = compositor->getMetricsState()->zone;
	bool wrapline = m_rWrapLine;

	// line width auto growth
	if ( zone.size.w == 0 )
		wrapline = false;
	
	RMetricsState* mstate = compositor->getMetricsState();

	RPos pen;
	RRect temp_linerect;
	short base_line_pos_y = 0;
	element_list_t::iterator inner_start_it = line->begin();
	line_marks.push_back(line->begin()); // push first line start
	for ( element_list_t::iterator it = line->begin(); it != line->end(); it++ )
	{
		RMetrics* metrics = (*it)->getMetrics();

		// prev composit event
		(*it)->onCachedCompositBegin(this, pen);

		// calculate baseline offset
		short baseline_correct = 0;
		if ( (*it)->needBaselineCorrect() )
		{
			baseline_correct = m_rBaselinePos;
		}

		// first element
		if ( pen.x == 0 )
		{
			pen.x -= metrics->rect.min_x();
		}
		
		// set position
		(*it)->setLocalPositionX(pen.x);
		(*it)->setLocalPositionY(pen.y + baseline_correct);

		RRect rect = metrics->rect;
		rect.pos.x += pen.x;
		rect.pos.y += baseline_correct;
		temp_linerect.extend(rect);

		// process wrapline
		element_list_t::iterator next_it = it + 1;
		if ( next_it == line->end() ||	// last element
			(*next_it)->isNewlineBefore() || // line-break before next element
			(*it)->isNewlineFollow() ||	// line-break after this element
			( wrapline && pen.x != 0		// wrap line
			&& pen.x + metrics->advance.x + (*next_it)->getMetrics()->rect.pos.x + (*next_it)->getMetrics()->rect.size.w + getPadding()*2 > zone.size.w 
			&& (*next_it)->canLinewrap() ) )
		{
			// correct out of bound correct
			short y2correct = -temp_linerect.max_y();

			for ( element_list_t::iterator inner_it = inner_start_it; inner_it != next_it; inner_it++ )
			{
				RPos pos = (*inner_it)->getLocalPosition();
				(*inner_it)->setLocalPositionY(pos.y + y2correct);
				(*inner_it)->setLocalPositionX(pos.x /*+ x2correct*/);
			}

			temp_linerect.pos.y = pen.y;
			line_rect.extend(temp_linerect);

			pen.y -= (temp_linerect.size.h + getSpacing());
			pen.x = 0;

			// push next line start
			line_marks.push_back(next_it);
			line_widths.push_back(temp_linerect.size.w);

			inner_start_it = next_it;
			temp_linerect = RRect();
		}
		else
		{
			pen.x += metrics->advance.x;
		}
		
		// post composit event
		(*it)->onCachedCompositEnd(this, pen);
	}

	short align_correct_x = 0;
	size_t line_mark_idx = 0;
	if ( getHAlign() == e_align_left )
		line_rect.size.w += getPadding() * 2;
	else
		line_rect.size.w = RMAX(zone.size.w, line_rect.size.w + getPadding() * 2); // auto rect
	for ( element_list_t::iterator it = line->begin(); it != line->end(); it++ )
	{
		// prev composit event
		(*it)->onCachedCompositBegin(this, pen);

		if ( it == line_marks[line_mark_idx] )
		{
			short lwidth = line_widths[line_mark_idx];

			// x correct
			switch ( getHAlign() )
			{
			case e_align_left:
				align_correct_x = getPadding();
				break;
			case e_align_center:
				align_correct_x = ( line_rect.size.w - lwidth ) / 2;
				break;
			case e_align_right:
				align_correct_x = line_rect.size.w - lwidth - getPadding();
				break;
			}

			line_mark_idx++; // until next line
		}

		RPos pos = (*it)->getLocalPosition();
		(*it)->setLocalPositionX(mstate->pen_x + pos.x + align_correct_x);
		(*it)->setLocalPositionY(mstate->pen_y + pos.y);

		// post composit event
		(*it)->onCachedCompositEnd(this, pen);
	}

	line_rect.pos.y = mstate->pen_y;

	// advance pen position
	mstate->pen_y -= (line_rect.size.h + getSpacing());
	mstate->pen_x = 0;
	
	clear();

	return line_rect;
}
Exemple #2
0
void
whilePaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
{
    switch (activeTool)
    {
        case TOOL_RUBBER:
            Replace(hdc, last.x, last.y, x, y, fg, bg, rubberRadius);
            break;
        case TOOL_PEN:
            Line(hdc, last.x, last.y, x, y, bg, 1);
            break;
        case TOOL_BRUSH:
            Brush(hdc, last.x, last.y, x, y, bg, brushStyle);
            break;
        case TOOL_AIRBRUSH:
            Airbrush(hdc, x, y, bg, airBrushWidth);
            break;
        case TOOL_LINE:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                roundTo8Directions(start.x, start.y, &x, &y);
            Line(hdc, start.x, start.y, x, y, bg, lineWidth);
            break;
        case TOOL_BEZIER:
            resetToU1();
            pointStack[pointSP].x = x;
            pointStack[pointSP].y = y;
            switch (pointSP)
            {
                case 1:
                    Line(hdc, pointStack[0].x, pointStack[0].y, pointStack[1].x, pointStack[1].y, bg,
                         lineWidth);
                    break;
                case 2:
                    Bezier(hdc, pointStack[0], pointStack[2], pointStack[2], pointStack[1], bg, lineWidth);
                    break;
                case 3:
                    Bezier(hdc, pointStack[0], pointStack[2], pointStack[3], pointStack[1], bg, lineWidth);
                    break;
            }
            break;
        case TOOL_RECT:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            Rect(hdc, start.x, start.y, x, y, bg, fg, lineWidth, shapeStyle);
            break;
        case TOOL_SHAPE:
            resetToU1();
            pointStack[pointSP].x = x;
            pointStack[pointSP].y = y;
            if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
                roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
                                   &pointStack[pointSP].x, &pointStack[pointSP].y);
            if (pointSP + 1 >= 2)
                Poly(hdc, pointStack, pointSP + 1, bg, fg, lineWidth, shapeStyle, FALSE);
            break;
        case TOOL_ELLIPSE:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            Ellp(hdc, start.x, start.y, x, y, bg, fg, lineWidth, shapeStyle);
            break;
        case TOOL_RRECT:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            RRect(hdc, start.x, start.y, x, y, bg, fg, lineWidth, shapeStyle);
            break;
    }

    last.x = x;
    last.y = y;
}
Exemple #3
0
void
endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
{
    switch (activeTool)
    {
        case TOOL_FREESEL:
        {
            POINT *ptStackCopy;
            int i;
            rectSel_src[0] = rectSel_src[1] = 0x7fffffff;
            rectSel_src[2] = rectSel_src[3] = 0;
            for (i = 0; i <= ptSP; i++)
            {
                if (ptStack[i].x < rectSel_src[0])
                    rectSel_src[0] = ptStack[i].x;
                if (ptStack[i].y < rectSel_src[1])
                    rectSel_src[1] = ptStack[i].y;
                if (ptStack[i].x > rectSel_src[2])
                    rectSel_src[2] = ptStack[i].x;
                if (ptStack[i].y > rectSel_src[3])
                    rectSel_src[3] = ptStack[i].y;
            }
            rectSel_src[2] += 1 - rectSel_src[0];
            rectSel_src[3] += 1 - rectSel_src[1];
            rectSel_dest[0] = rectSel_src[0];
            rectSel_dest[1] = rectSel_src[1];
            rectSel_dest[2] = rectSel_src[2];
            rectSel_dest[3] = rectSel_src[3];
            if (ptSP != 0)
            {
                DeleteObject(hSelMask);
                hSelMask = CreateBitmap(rectSel_src[2], rectSel_src[3], 1, 1, NULL);
                DeleteObject(SelectObject(hSelDC, hSelMask));
                ptStackCopy = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * (ptSP + 1));
                for (i = 0; i <= ptSP; i++)
                {
                    ptStackCopy[i].x = ptStack[i].x - rectSel_src[0];
                    ptStackCopy[i].y = ptStack[i].y - rectSel_src[1];
                }
                Poly(hSelDC, ptStackCopy, ptSP + 1, 0x00ffffff, 0x00ffffff, 1, 2, TRUE);
                HeapFree(GetProcessHeap(), 0, ptStackCopy);
                SelectObject(hSelDC, hSelBm = CreateDIBWithProperties(rectSel_src[2], rectSel_src[3]));
                resetToU1();
                MaskBlt(hSelDC, 0, 0, rectSel_src[2], rectSel_src[3], hDrawingDC, rectSel_src[0],
                        rectSel_src[1], hSelMask, 0, 0, MAKEROP4(SRCCOPY, WHITENESS));
                Poly(hdc, ptStack, ptSP + 1, bg, bg, 1, 2, TRUE);
                newReversible();

                MaskBlt(hDrawingDC, rectSel_src[0], rectSel_src[1], rectSel_src[2], rectSel_src[3], hSelDC, 0,
                        0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));

                placeSelWin();
                ShowWindow(hSelection, SW_SHOW);
                /* force refresh of selection contents */
                SendMessage(hSelection, WM_LBUTTONDOWN, 0, 0);
                SendMessage(hSelection, WM_MOUSEMOVE, 0, 0);
                SendMessage(hSelection, WM_LBUTTONUP, 0, 0);
            }
            HeapFree(GetProcessHeap(), 0, ptStack);
            ptStack = NULL;
            break;
        }
        case TOOL_RECTSEL:
            resetToU1();
            if ((rectSel_src[2] != 0) && (rectSel_src[3] != 0))
            {
                DeleteObject(hSelMask);
                hSelMask = CreateBitmap(rectSel_src[2], rectSel_src[3], 1, 1, NULL);
                DeleteObject(SelectObject(hSelDC, hSelMask));
                Rect(hSelDC, 0, 0, rectSel_src[2], rectSel_src[3], 0x00ffffff, 0x00ffffff, 1, 2);
                SelectObject(hSelDC, hSelBm = CreateDIBWithProperties(rectSel_src[2], rectSel_src[3]));
                resetToU1();
                BitBlt(hSelDC, 0, 0, rectSel_src[2], rectSel_src[3], hDrawingDC, rectSel_src[0],
                       rectSel_src[1], SRCCOPY);
                Rect(hdc, rectSel_src[0], rectSel_src[1], rectSel_src[0] + rectSel_src[2],
                     rectSel_src[1] + rectSel_src[3], bgColor, bgColor, 0, TRUE);
                newReversible();

                BitBlt(hDrawingDC, rectSel_src[0], rectSel_src[1], rectSel_src[2], rectSel_src[3], hSelDC, 0,
                       0, SRCCOPY);

                placeSelWin();
                ShowWindow(hSelection, SW_SHOW);
                /* force refresh of selection contents */
                SendMessage(hSelection, WM_LBUTTONDOWN, 0, 0);
                SendMessage(hSelection, WM_MOUSEMOVE, 0, 0);
                SendMessage(hSelection, WM_LBUTTONUP, 0, 0);
            }
            break;
        case TOOL_RUBBER:
            Erase(hdc, last.x, last.y, x, y, bg, rubberRadius);
            break;
        case TOOL_PEN:
            Line(hdc, last.x, last.y, x, y, fg, 1);
            SetPixel(hdc, x, y, fg);
            break;
        case TOOL_LINE:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                roundTo8Directions(start.x, start.y, &x, &y);
            Line(hdc, start.x, start.y, x, y, fg, lineWidth);
            break;
        case TOOL_BEZIER:
            pointSP++;
            if (pointSP == 4)
                pointSP = 0;
            break;
        case TOOL_RECT:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            Rect(hdc, start.x, start.y, x, y, fg, bg, lineWidth, shapeStyle);
            break;
        case TOOL_SHAPE:
            resetToU1();
            pointStack[pointSP].x = x;
            pointStack[pointSP].y = y;
            if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
                roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
                                   &pointStack[pointSP].x, &pointStack[pointSP].y);
            pointSP++;
            if (pointSP >= 2)
            {
                if ((pointStack[0].x - x) * (pointStack[0].x - x) +
                    (pointStack[0].y - y) * (pointStack[0].y - y) <= lineWidth * lineWidth + 1)
                {
                    Poly(hdc, pointStack, pointSP, fg, bg, lineWidth, shapeStyle, TRUE);
                    pointSP = 0;
                }
                else
                {
                    Poly(hdc, pointStack, pointSP, fg, bg, lineWidth, shapeStyle, FALSE);
                }
            }
            if (pointSP == 255)
                pointSP--;
            break;
        case TOOL_ELLIPSE:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            Ellp(hdc, start.x, start.y, x, y, fg, bg, lineWidth, shapeStyle);
            break;
        case TOOL_RRECT:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            RRect(hdc, start.x, start.y, x, y, fg, bg, lineWidth, shapeStyle);
            break;
    }
}
Exemple #4
0
void
whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
{
    switch (activeTool)
    {
        case TOOL_FREESEL:
            if (ptSP == 0)
                newReversible();
            ptSP++;
            if (ptSP % 1024 == 0)
                ptStack = HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, ptStack, sizeof(POINT) * (ptSP + 1024));
            ptStack[ptSP].x = max(0, min(x, imgXRes));
            ptStack[ptSP].y = max(0, min(y, imgYRes));
            resetToU1();
            Poly(hdc, ptStack, ptSP + 1, 0, 0, 2, 0, FALSE);
            break;
        case TOOL_RECTSEL:
        {
            POINT temp;
            resetToU1();
            temp.x = max(0, min(x, imgXRes));
            temp.y = max(0, min(y, imgYRes));
            rectSel_dest[0] = rectSel_src[0] = min(start.x, temp.x);
            rectSel_dest[1] = rectSel_src[1] = min(start.y, temp.y);
            rectSel_dest[2] = rectSel_src[2] = max(start.x, temp.x) - min(start.x, temp.x);
            rectSel_dest[3] = rectSel_src[3] = max(start.y, temp.y) - min(start.y, temp.y);
            RectSel(hdc, start.x, start.y, temp.x, temp.y);
            break;
        }
        case TOOL_RUBBER:
            Erase(hdc, last.x, last.y, x, y, bg, rubberRadius);
            break;
        case TOOL_PEN:
            Line(hdc, last.x, last.y, x, y, fg, 1);
            break;
        case TOOL_BRUSH:
            Brush(hdc, last.x, last.y, x, y, fg, brushStyle);
            break;
        case TOOL_AIRBRUSH:
            Airbrush(hdc, x, y, fg, airBrushWidth);
            break;
        case TOOL_LINE:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                roundTo8Directions(start.x, start.y, &x, &y);
            Line(hdc, start.x, start.y, x, y, fg, lineWidth);
            break;
        case TOOL_BEZIER:
            resetToU1();
            pointStack[pointSP].x = x;
            pointStack[pointSP].y = y;
            switch (pointSP)
            {
                case 1:
                    Line(hdc, pointStack[0].x, pointStack[0].y, pointStack[1].x, pointStack[1].y, fg,
                         lineWidth);
                    break;
                case 2:
                    Bezier(hdc, pointStack[0], pointStack[2], pointStack[2], pointStack[1], fg, lineWidth);
                    break;
                case 3:
                    Bezier(hdc, pointStack[0], pointStack[2], pointStack[3], pointStack[1], fg, lineWidth);
                    break;
            }
            break;
        case TOOL_RECT:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            Rect(hdc, start.x, start.y, x, y, fg, bg, lineWidth, shapeStyle);
            break;
        case TOOL_SHAPE:
            resetToU1();
            pointStack[pointSP].x = x;
            pointStack[pointSP].y = y;
            if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
                roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
                                   &pointStack[pointSP].x, &pointStack[pointSP].y);
            if (pointSP + 1 >= 2)
                Poly(hdc, pointStack, pointSP + 1, fg, bg, lineWidth, shapeStyle, FALSE);
            break;
        case TOOL_ELLIPSE:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            Ellp(hdc, start.x, start.y, x, y, fg, bg, lineWidth, shapeStyle);
            break;
        case TOOL_RRECT:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            RRect(hdc, start.x, start.y, x, y, fg, bg, lineWidth, shapeStyle);
            break;
    }

    last.x = x;
    last.y = y;
}
Exemple #5
0
void CScrollBar::CalcRects(int y /*= 0*/)
{
	const int &cx = m_mdc.cx;
	const int &cy = m_mdc.cy;

	const int cxBtn = GetSystemMetrics(SM_CXHTHUMB);
	const int cyBtn = cxBtn + SCX(1);

	// Buttons

	m_rcBtn1 = RRect(0, 0, cxBtn, cyBtn);
	m_rcBtn2 = RRect(0, cy - cyBtn, cxBtn, cy);

	// Thumb

	m_rcThumb.x = 0;
	m_rcThumb.cx = cxBtn;
	
	int nFullRange = m_nRangeMax - m_nRangeMin + 1;
	int nVarRange = nFullRange - m_nPageSize;

	if (nVarRange <= 0)
		return;

	int cyFullRange = cy - 2 * cyBtn;
	m_rcThumb.cy = max((m_nPageSize * cyFullRange) / nFullRange, SCX(20));
	int cyVarRange = cyFullRange - m_rcThumb.cy;

	if (cyVarRange <= 0)
		return;

	if (m_bDragging)
	{
		// Calculate virtual thumb position from mouse position and correct it

		m_rcThumb = m_rcDragging;
		m_rcThumb.y += y - m_ptDragging.y;

		if (m_rcThumb.y < cyBtn)
			m_rcThumb.y = cyBtn;

		if (m_rcThumb.bottom > cy - cyBtn)
			m_rcThumb.y -= m_rcThumb.bottom - (cy - cyBtn);

		// Calculate track position from virtual thumb position

		double dVarPos = (double)(m_rcThumb.y - cyBtn) / cyVarRange;
		int nTrackPos = m_nRangeMin + round(dVarPos * nVarRange);
		
		if (m_nTrackPos != nTrackPos)
		{
			m_nTrackPos = nTrackPos;
			PostMessage(GetParent(m_hWnd), WM_VSCROLL, 
					MAKEWPARAM(SB_THUMBTRACK, m_nTrackPos), (LPARAM)m_hWnd);
		}

		// Calculate thumb position from track position

		m_rcThumb.y = cyBtn + round((double)((m_nTrackPos - m_nRangeMin) * 
				cyVarRange) / nVarRange);
	}
	else
	{
		m_rcThumb.y = cyBtn + round((double)((m_nPos - m_nRangeMin) * 
				cyVarRange) / nVarRange);

		// Calculate page up and down rectangles

		m_rcBtnPageUp = RRect(0, cyBtn, cxBtn, m_rcThumb.top);
		m_rcBtnPageDown = RRect(0, m_rcThumb.bottom, cxBtn, cy - cyBtn);
	}

	
}
Exemple #6
-1
void
endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
{
    switch (activeTool)
    {
        case TOOL_RUBBER:
            Replace(hdc, last.x, last.y, x, y, fg, bg, rubberRadius);
            break;
        case TOOL_PEN:
            Line(hdc, last.x, last.y, x, y, bg, 1);
            SetPixel(hdc, x, y, bg);
            break;
        case TOOL_LINE:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                roundTo8Directions(start.x, start.y, &x, &y);
            Line(hdc, start.x, start.y, x, y, bg, lineWidth);
            break;
        case TOOL_BEZIER:
            pointSP++;
            if (pointSP == 4)
                pointSP = 0;
            break;
        case TOOL_RECT:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            Rect(hdc, start.x, start.y, x, y, bg, fg, lineWidth, shapeStyle);
            break;
        case TOOL_SHAPE:
            resetToU1();
            pointStack[pointSP].x = x;
            pointStack[pointSP].y = y;
            if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
                roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
                                   &pointStack[pointSP].x, &pointStack[pointSP].y);
            pointSP++;
            if (pointSP >= 2)
            {
                if ((pointStack[0].x - x) * (pointStack[0].x - x) +
                    (pointStack[0].y - y) * (pointStack[0].y - y) <= lineWidth * lineWidth + 1)
                {
                    Poly(hdc, pointStack, pointSP, bg, fg, lineWidth, shapeStyle, TRUE);
                    pointSP = 0;
                }
                else
                {
                    Poly(hdc, pointStack, pointSP, bg, fg, lineWidth, shapeStyle, FALSE);
                }
            }
            if (pointSP == 255)
                pointSP--;
            break;
        case TOOL_ELLIPSE:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            Ellp(hdc, start.x, start.y, x, y, bg, fg, lineWidth, shapeStyle);
            break;
        case TOOL_RRECT:
            resetToU1();
            if (GetAsyncKeyState(VK_SHIFT) < 0)
                regularize(start.x, start.y, &x, &y);
            RRect(hdc, start.x, start.y, x, y, bg, fg, lineWidth, shapeStyle);
            break;
    }
}