⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pw_draw.c

📁 Very very small GUI. Usefull for small system, without OS or small OS. Event driven, support user m
💻 C
📖 第 1 页 / 共 3 页
字号:
            bits++;            rx += 8;        }        y++;    }    IPW_TRACE_EXIT(DR2);}/** *  Draws a bitmap with clipping. *  @param gc   pointer to graphic context *  @param x    x coord of bitmap's top left corner *  @param y    y coord of bitmap's top left corner *  @param w    bitmap's width  *  @param h    bitmap's height *  @param bits bitmap bits array *  @param clip pointer to clip rectangle *  @internal */ static void _DrawClipBitmap(Pw_GC*        gc,                 Pw_Coord      x,                 Pw_Coord      y,                 Pw_Coord      w,                 Pw_Coord      h,                 Pw_Byte*      bits,                Pw_Rectangle* clip) {    Pw_Coord w8;h = h;    IPW_TRACE_ENTER(DR2);    IPW_TRACE4(DR2, d, x, y, w, h);    IPW_TRACE_RECT(DR2, clip);    /*     *  Calculate bitmap's width in bytes and clip the top of the bitmap     */    w8 = (w + 0x07) >> 3;           bits += (clip->y - y) * w8;     /*     * When drawing a clipped bitmap we have two different cases:     *      * 1. the visible part of bitmap is greater then 8 pixels - then     *    we have some or none bits on left, 1 or more bytes in the     *    middle and some or none bits on the right.     *     * 2. the visible part is less then or equal 8 pixels - then the     *    visible bitmap bits can be all in one bitmap byte or can span      *    over two bytes.     */     if (clip->w > 8)    {        /* The visible part is greater then 8 pixels */        Pw_uInt  left_bytes, right_bytes, middle_bytes;        Pw_uInt  left_bits, right_bits, i, j;        Pw_Coord cx;        /* Calc bitmap's left side bytes and bits to clip */        left_bits   = clip->x - x;        left_bytes  = left_bits >> 3;        left_bits  &= 0x07;        /* Calc bitmap's right side bytes and bits to clip */        right_bits   = x + (w8 << 3) - clip->x - clip->w;        right_bytes  = right_bits >> 3;        right_bits  &= 0x07;        /* Calc bitmap's visible bytes */        middle_bytes = w8 - left_bytes - right_bytes;        IPW_TRACE2(DR2, d, left_bits, right_bits);        IPW_TRACE3(DR2, d, left_bytes, right_bytes, middle_bytes);        if (left_bits != 0)            middle_bytes--;        if (right_bits != 0)        {            right_bits = 8 - right_bits;            middle_bytes--;        }        /* Set x and y to top left corner of bitmap's visible part */        y = clip->y;        x = clip->x - left_bits;        /* Get left and right side visible bits mask */         left_bits  = _bm_edgemask[0][left_bits];        right_bits = _bm_edgemask[1][right_bits];        /* Draw bitmap lines */        for (j = 0; j < clip->h; j++)        {            cx = x;            /* Skip invisible bytes on left */            bits += left_bytes;                        if (left_bits != 0)            {                /* Draw visible bits on left */                gc->d.lld->draw_points(gc, cx, y, (*bits & left_bits));                bits++;                cx += 8;            }            /* Draw visible bytes */            for (i = 0; i < middle_bytes; i++)            {                gc->d.lld->draw_points(gc, cx, y, *bits);                bits++;                cx += 8;            }            /* Draw visible bits on right */            if (right_bits != 0)            {                gc->d.lld->draw_points(gc, cx, y, (*bits & right_bits));                bits++;            }            /* Skip invisible bytes on right */            bits += right_bytes;             y++;        }    }    else     {        /* The visible part is less then or equal 8 pixels */        Pw_uInt i, mask;        Pw_Byte left_bits, right_bits;        /* Clip invisible bytes on left (in first visible line) */        bits += (clip->x - x) >> 3;        /* Calc invisible bits on left */        left_bits = (clip->x - x) & 0x07;        /* Calc the visible bits mask */        mask = _bm_edgemask[1][clip->w];        mask = (mask << 8) >> left_bits;            /* Set x and y to top left corner of bitmap's visible part */        y = clip->y;        x = clip->x - left_bits;        /* Get the left and right part of visible bits mask */        left_bits  = mask >> 8;        right_bits = mask & 0x00FF;        IPW_TRACE2(DR2, d, left_bits, right_bits);         /* Draw bitmap lines */        for (i = 0; i < clip->h; i++)        {            /* If left part of mask has any visible bits draw them */            if (left_bits != 0)                gc->d.lld->draw_points(gc, x, y, (*bits & left_bits));            /* Next bitmap's byte */            bits++;            /* If right part of mask has any visible bits draw them */            if (right_bits != 0)                gc->d.lld->draw_points(gc, x+8, y, (*bits & right_bits));            /* Skip invisible bytes on right and left */            bits += w8 - 1;            y++;        }    }    IPW_TRACE_EXIT(DR2);}/* -------------------------------------------------------------------------- */#if IPW_CHECK_EN(GC_STRUCT)Pw_Bool IPw_GCCheck(Pw_GC* gc){
return TRUE;								/// !!!!!    if (PW_NULL == gc->d.lld)    {        IPW_ASSERT(FALSE, ("GC (%p) lld == NULL!", gc));        return(FALSE);    }    if (PW_NULL == gc->d.lld->draw_point    ||        PW_NULL == gc->d.lld->draw_points   ||        PW_NULL == gc->d.lld->draw_hor_line ||        PW_NULL == gc->d.lld->draw_ver_line ||        PW_NULL == gc->d.lld->fill_rect)    {        IPW_ASSERT(FALSE, ("GC (%p) some lld funcs == NULL!", gc));        return(FALSE);    }    if (Pw_DrawableWindowType == gc->d.type && PW_NULL == gc->d.comp.window)    {        IPW_ASSERT(FALSE, ("GC (%p) window == NULL!", gc));        return(FALSE);    }    if (Pw_DrawableBitmapType == gc->d.type && PW_NULL == gc->d.comp.bitmap)    {        IPW_ASSERT(FALSE, ("GC (%p) bitmap == NULL!", gc));        return(FALSE);    }/*    if (PW_NULL == gc->color)    {        IPW_ASSERT(FALSE, ("GC (%p) color == NULL!", gc));        return(FALSE);    }	*/    if (PW_NULL != gc->font)    {        if (PW_NULL == gc->font->bits)        {            IPW_ASSERT(FALSE, ("GC (%p) font bits == NULL!", gc));            return(FALSE);        }        if (PW_NULL == gc->font->info)        {            IPW_ASSERT(FALSE, ("GC (%p) font info == NULL!", gc));            return(FALSE);        }    }#if IPW_CHECK_EN(REGION_LIST)    if (!IPw_RegionListCheck(&gc->clip_reg, TRUE))    {        IPW_ASSERT(FALSE, ("GC (%p) clip region check failed!", gc));        return(FALSE);    }#endif /* IPW_CHECK_EN(REGION_LIST) */    return(TRUE);}#endif /* IPW_CHECK_EN(GC_STRUCT) *//* -------------------------------------------------------------------------- *//** *  Gets the width of string @p string according  *  to the @p font. *  @param font   pointer to font   *  @param string string *  @return width of string in screen pixels */ Pw_uInt Pw_FontGetStringWidth(Pw_Font* font, Pw_Char* string){    Pw_uInt w = 0;    IPW_TRACE_ENTER(DR3);    IPW_CHECK_PTR2(font, string);    /* Sum widths of all charachters in string */    while (*string != '\0')    {        w += font->info[(Pw_Byte)*string].dwx;        string++;    }    IPW_TRACE_EXIT_V(DR3, d, w);    return(w);}/** *  Draws a point. *  @param gc pointer to graphic context *  @param x  x coord  *  @param y  y coord  */void Pw_DrawPoint(Pw_GC* gc, Pw_Coord x, Pw_Coord y){    Pw_Region* reg;    IPW_TRACE_ENTER(DR3);    IPW_CHECK_PTR(gc);    IPW_CHECK_GC(gc);    IPW_TRACE2(DR3, d, x, y);    /* Correct point's coords according to the graphic context origin */    x += gc->xoff;    y += gc->yoff;    IPW_TRACE2(DR3, d, x, y);    IPW_TRACE_RECT(DR3, &gc->clip_reg.bounds);    /* Check if point is inside clip region bounds */    if (!IPW_RECT_IS_POINT_IN(x, y, &gc->clip_reg.bounds))    {        IPW_TRACE_EXIT(DR3);        return;    }    /*      * Check if the point is inside the clip region and draw it accordingly     */    reg = gc->clip_reg.regs;    while (PW_NULL != reg)    {        IPW_TRACE_RECT(DR3, &reg->area);          if (IPW_RECT_IS_POINT_IN(x, y, &reg->area))        {            gc->d.lld->draw_point(gc, x, y);            IPW_TRACE_EXIT(DR3);            return;        }        reg = reg->next;    }    IPW_TRACE_EXIT(DR3);}/** *  Draws a rectangle. *  @param gc     pointer to graphic context *  @param x      x coord (of the top left corner)  *  @param y      y coord (of the top left corner) *  @param width  width of rectangle *  @param height height of rectangle *  @see Pw_FillRect */void Pw_DrawRect(Pw_GC*   gc,             Pw_Coord x,             Pw_Coord y,             Pw_Coord w,             Pw_Coord h){    Pw_Coord     rx2, ry2;    Pw_Rectangle r, rc;    Pw_Region*   reg;    IPW_TRACE_ENTER(DR3);    IPW_CHECK_PTR(gc);    IPW_CHECK_GC(gc);    IPW_TRACE4(DR3, d, x, y, w, h);    /* Correct rectangle position according to graphic context origin */    r.x = x + gc->xoff;    r.y = y + gc->yoff;    r.w = w;    r.h = h;    IPW_TRACE_RECT2(DR3, &r, &gc->clip_reg.bounds);    /* Check if rectangle intersects clip region bounds */    if (!IPW_RECT_IS_OVER(&r, &gc->clip_reg.bounds))    {        IPW_TRACE_EXIT(DR3);        return;    }    /* Calc rectangle bottom right corner coords */    rx2 = r.x + r.w - 1;    ry2 = r.y + r.h - 1;    /*     * Check each rectangle in clip region - if our     * rectangle intersect one of them, than draw     * the visible part     */    reg = gc->clip_reg.regs;    while (PW_NULL != reg)    {        IPW_TRACE_RECT(DR3, &reg->area);         /* Make a copy of rectangle */        IPW_RECT_COPY(&rc, &r);        /*          * If rectangle intersects current          * clip region rectangle than draw it          */         if (IPw_RectIntersect(&rc, &reg->area))        {            IPW_TRACE_RECT(DR3, &rc);              if (IPW_RECT_IS_EQUAL(&r, &rc))             {                /* Rectangle fully visible - draw it and we are done */                gc->d.lld->draw_ver_line(gc, r.x, r.y, ry2);                gc->d.lld->draw_ver_line(gc, rx2, r.y, ry2);                gc->d.lld->draw_hor_line(gc, r.x, r.y, rx2);                gc->d.lld->draw_hor_line(gc, r.x, ry2, rx2);                IPW_TRACE_EXIT(DR3);                return;            }            else            {                Pw_Coord rcx2, rcy2;                /* Calc clipped rectangle bottom right corner coords */                rcx2 = rc.x + rc.w - 1;                rcy2 = rc.y + rc.h - 1;                /* Draw parts of rectangle that are visible */                if (r.x == rc.x)                    gc->d.lld->draw_ver_line(gc, rc.x, rc.y, rcy2);                if (rx2 == rcx2)                    gc->d.lld->draw_ver_line(gc, rcx2, rc.y, rcy2);                if (r.y == rc.y)                    gc->d.lld->draw_hor_line(gc, rc.x, rc.y, rcx2);                if (ry2 == rcy2)                    gc->d.lld->draw_hor_line(gc, rc.x, rcy2, rcx2);            }        }        reg = reg->next;    }    IPW_TRACE_EXIT(DR3);}/** *  Draws a filled rectangle. *  @param gc     pointer to graphic context *  @param x      x coord (of the top left corner)  *  @param y      y coord (of the top left corner) *  @param width  width of rectangle *  @param height height of rectangle *  @see Pw_DrawRect */void Pw_FillRect(Pw_GC*   gc,             Pw_Coord x,             Pw_Coord y,             Pw_Coord w,             Pw_Coord h){    Pw_Rectangle r, rc;    Pw_Region*   reg;    IPW_TRACE_ENTER(DR3);    IPW_CHECK_PTR(gc);    IPW_CHECK_GC(gc);    IPW_TRACE4(DR3, d, x, y, w, h);    /* Correct rectangle position according to graphic context origin */    r.x = x + gc->xoff;    r.y = y + gc->yoff;    r.w = w;    r.h = h;    IPW_TRACE_RECT2(DR3, &r, &gc->clip_reg.bounds);    /*     * Check if rectangle's bounding box intersects the clip region     * bounding box     */     if (!IPW_RECT_IS_OVER(&r, &gc->clip_reg.bounds))    {        IPW_TRACE_EXIT(DR3);        return;    }    /*     * Check each rectangle in clip region - if our     * rectangle intersect one of them, than draw     * the visible part     */    reg = gc->clip_reg.regs;    while (PW_NULL != reg)    {        IPW_TRACE_RECT(DR3, &reg->area);        /* Make a copy of rectangle */        IPW_RECT_COPY(&rc, &r);        /* Intersect the rectangle with current clip region rectangle */        if (IPw_RectIntersect(&rc, &reg->area))        {            IPW_TRACE_RECT(DR3, &rc);             /* Draw the intersected rectangle */            gc->d.lld->fill_rect(gc, rc.x, rc.y, rc.w, rc.h);            /*              * If intersected rectangle equals the              * original rectangle - we are done             */             if (IPW_RECT_IS_EQUAL(&r, &rc))             {                IPW_TRACE_EXIT(DR3);                return;            }        }        reg = reg->next;    }    IPW_TRACE_EXIT(DR3);}/** *  Draws a line. *  @param gc pointer to graphic context *  @param x1 x coord (of start point)  *  @param y1 y coord (of start point) *  @param x2 x coord (of end point)  *  @param y2 y coord (of end point) */void Pw_DrawLine(Pw_GC*   gc,             Pw_Coord x1,             Pw_Coord y1,             Pw_Coord x2,             Pw_Coord y2){    Pw_Region* reg;    IPW_TRACE_ENTER(DR3);    IPW_CHECK_PTR(gc);    IPW_CHECK_GC(gc);    IPW_TRACE4(DR3, d, x1, y1, x2, y2);    /* Correct the line coords according to graphic context origin */    x1 += gc->xoff;    x2 += gc->xoff;    y1 += gc->yoff;    y2 += gc->yoff;    IPW_TRACE4(DR3, d, x1, y1, x2, y2);    IPW_TRACE_RECT(DR3, &gc->clip_reg.bounds);    /* If line outside clip region bounds return */    if ((IPw_RectOutCode(&gc->clip_reg.bounds, x1, y1) &         IPw_RectOutCode(&gc->clip_reg.bounds, x2, y2)) != 0)    {        IPW_TRACE_EXIT(DR3);        return;    }    reg = gc->clip_reg.regs;    /*      * Check if line is an horizontal or vertical line -     * if it is use faster drawing and clipping functions     */      if (x1 == x2)    {        /* Horizontal line */        /*         * Check each rectangle in clip region - if our         * line intersect one of them, than draw the         * visible part         */        while (PW_NULL != reg)        {            IPW_TRACE_RECT(DR3, &reg->area);             if (_DrawClipVerLine(gc, x1, y1, y2, &reg->area))            {                IPW_TRACE_EXIT(DR3);                return;            }            reg = reg->next;        }    }    else if (y1 == y2)     {        /* Vertical line */        /*         * Check each rectangle in clip region - if our         * line intersect one of them, than draw the         * visible part         */        while (PW_NULL != reg)        {            IPW_TRACE_RECT(DR3, &reg->area);            if (_DrawClipHorLine(gc, x1, y1, x2, &reg->area))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -