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

📄 drawtext.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
                if (x % 8 == 0)
                    b = *bits++;
                if ((b & (128 >> (x % 8)))) {
                    *(Uint32 *) expanded = fg;
                    if (bold)
                        *(Uint32 *) (expanded + 4) = fg;
                }

                expanded += 4;
            }
            line += line_bytes;
        }
    }

    return line_bytes;
}

/* return width of output */
static void put_one_char (PDC pdc, LOGFONT* logfont, DEVFONT* devfont,
                int* px, int* py, int h, int ascent, const char* mchar, int len)
{
    const BYTE* bits;
    BYTE* expanded;
    int bbox_x = *px, bbox_y = *py;
    int bbox_w, bbox_h, bold = 0, italic = 0;
    int line_bytes;
    int bpp, pitch = 0;
    int old_x, old_y;
    
    if (devfont->font_ops->get_char_bbox) {
        (*devfont->font_ops->get_char_bbox) (logfont, devfont,
                            mchar, len, &bbox_x, &bbox_y, &bbox_w, &bbox_h);
    }
    else {
        bbox_w = (*devfont->font_ops->get_char_width) (logfont, devfont, 
                mchar, len);
        bbox_h = h;
        bbox_y -= ascent;
    }

    if (logfont->style & FS_WEIGHT_BOLD 
        && !(devfont->style & FS_WEIGHT_BOLD)) {
        bold = 1;
    }
    if (logfont->style & FS_SLANT_ITALIC
        && !(devfont->style & FS_SLANT_ITALIC)) {
        italic = (bbox_h - 1) >> 1;
    }

    if (logfont->style & FS_WEIGHT_BOOK
            && devfont->font_ops->get_char_pixmap) {
        bits = (*devfont->font_ops->get_char_pixmap) (logfont, devfont, 
                mchar, len, &pitch);
    }
    else {
        bits = (*devfont->font_ops->get_char_bitmap) (logfont, devfont, 
                mchar, len);
    }

    if (bits == NULL)
        return;

    old_x = *px; old_y = *py;
    if (devfont->font_ops->get_char_advance) {
        (*devfont->font_ops->get_char_advance) (logfont, devfont, mchar, len, px, py);
        /* erase background here */
        if (pdc->bkmode != BM_TRANSPARENT && old_y == *py) {
            int bk_x, bk_w;
            if (*px > old_x) {
                bk_x = old_x;
                bk_w = *px - old_x;
            }
            else {
                bk_x = *px;
                bk_w = old_x - *px;
            }
            GAL_SetFgColor (pdc->gc, pdc->bkcolor);
            GAL_FillBox (pdc->gc, bk_x, old_y - ascent, bk_w, h, pdc->bkcolor); 
        }
    }
    else
        *px += bbox_w + bold;

    bpp = GAL_BytesPerPixel (pdc->gc);
    expanded = get_buffer ((bbox_w + bold + italic) * bbox_h * bpp);

    if (pdc->bkmode == BM_TRANSPARENT || italic != 0)
        GAL_GetBox (pdc->gc, bbox_x, bbox_y, (bbox_w + bold + italic), bbox_h, expanded);

    if (logfont->style & FS_WEIGHT_BOOK
            && devfont->font_ops->get_char_pixmap) {
        line_bytes = expand_char_pixmap (pdc, bbox_w, bbox_h, bits, expanded,
                pdc->bkmode != BM_TRANSPARENT, bold, italic, pitch);
    }
    else {
        line_bytes = expand_char_bitmap (bbox_w, bbox_h, bits, bpp,
                expanded, pdc->bkcolor, pdc->textcolor, 
                pdc->bkmode != BM_TRANSPARENT, bold, italic);
    }

    GAL_PutBox (pdc->gc, bbox_x, bbox_y, (bbox_w + bold + italic), bbox_h, expanded);
}

static void draw_text_lines (PDC pdc, PLOGFONT logfont, int x1, int y1, int x2, int y2)
{
    int h = logfont->size;

    if (x1 == x2 && y1 == y2)
        return;

    GAL_SetFgColor (pdc->gc, pdc->textcolor);
    if (logfont->style & FS_UNDERLINE_LINE) {
        GAL_Line (pdc->gc, x1, y1, x2, y2, pdc->textcolor);
    }

    if (logfont->style & FS_STRUCKOUT_LINE) {
        GAL_Line (pdc->gc, x1, y1 - (h >> 1), x2, y2 - (h >> 1), pdc->textcolor);
    }
}

/* return width of output */
int gdi_strnwrite (PDC pdc, int x, int y, const char* text, int len)
{
    DEVFONT* sbc_devfont = pdc->pLogFont->sbc_devfont;
    DEVFONT* mbc_devfont = pdc->pLogFont->mbc_devfont;
    int len_cur_char;
    int left_bytes = len;
    int origx, origy;
    int sbc_height = (*sbc_devfont->font_ops->get_font_height) (pdc->pLogFont, sbc_devfont);
    int sbc_ascent = (*sbc_devfont->font_ops->get_font_ascent) (pdc->pLogFont, sbc_devfont);
    int mbc_height = 0;
    int mbc_ascent = 0;

    if (mbc_devfont) {
        mbc_height = (*mbc_devfont->font_ops->get_font_height) (pdc->pLogFont, mbc_devfont);
        mbc_ascent = (*mbc_devfont->font_ops->get_font_ascent) (pdc->pLogFont, mbc_devfont);
    }

    y += MAX (sbc_ascent, mbc_ascent); /* convert y-coordinate to baseline */
    y += pdc->alExtra;

    origx = x;
    origy = y;

    gdi_start_new_line (pdc->pLogFont);
    while (left_bytes > 0) {
        if (mbc_devfont != NULL) {
            len_cur_char = (*mbc_devfont->charset_ops->len_first_char) (text, left_bytes);
            if (len_cur_char != 0) {
                put_one_char (pdc, pdc->pLogFont, mbc_devfont, &x, &y, 
                                    mbc_height, mbc_ascent, text, len_cur_char);
                
                left_bytes -= len_cur_char;
                text += len_cur_char;
                x += pdc->cExtra;
                continue;
            }
        }

        len_cur_char = (*sbc_devfont->charset_ops->len_first_char) (text, left_bytes);
        if (len_cur_char != 0)
            put_one_char (pdc, pdc->pLogFont, sbc_devfont, &x, &y, 
                                    sbc_height, sbc_ascent, text, len_cur_char);
        else
            break;

        left_bytes -= len_cur_char;
        text += len_cur_char;
        x += pdc->cExtra;
    }

    draw_text_lines (pdc, pdc->pLogFont, origx, origy, x, y);

    return x - origx;
}

int gdi_tabbedtextout (PDC pdc, int x, int y, const char* text, int len)
{
    DEVFONT* sbc_devfont = pdc->pLogFont->sbc_devfont;
    DEVFONT* mbc_devfont = pdc->pLogFont->mbc_devfont;
    int len_cur_char;
    int left_bytes = len;
    int origx, origy;
    int x_start = x, max_x = x;
    int tab_width, line_height;

    int sbc_height = (*sbc_devfont->font_ops->get_font_height) (pdc->pLogFont, sbc_devfont);
    int mbc_height = 0;
    int sbc_ascent = (*sbc_devfont->font_ops->get_font_ascent) (pdc->pLogFont, sbc_devfont);
    int mbc_ascent = 0;

    if (mbc_devfont) {
        mbc_height = (*mbc_devfont->font_ops->get_font_height) (pdc->pLogFont, mbc_devfont);
        mbc_ascent = (*mbc_devfont->font_ops->get_font_ascent) (pdc->pLogFont, mbc_devfont);
    }

    y += MAX (sbc_ascent, mbc_ascent);
    y += pdc->alExtra;

    origx = x; origy = y;

    tab_width = (*sbc_devfont->font_ops->get_ave_width) (pdc->pLogFont, 
                    sbc_devfont) * pdc->tabstop;
    line_height = pdc->pLogFont->size + pdc->alExtra + pdc->blExtra;

    gdi_start_new_line (pdc->pLogFont);
    while (left_bytes > 0) {
        if (mbc_devfont != NULL) {
            len_cur_char = (*mbc_devfont->charset_ops->len_first_char) (text, left_bytes);
            if (len_cur_char != 0) {
                put_one_char (pdc, pdc->pLogFont, mbc_devfont, &x, &y, 
                                        mbc_height, mbc_ascent, text, len_cur_char);
                x += pdc->cExtra;
                left_bytes -= len_cur_char;
                text += len_cur_char;
                continue;
            }
        }

        len_cur_char = (*sbc_devfont->charset_ops->len_first_char) (text, left_bytes);
        if (len_cur_char != 0)
            switch (*text) {
            case '\n':
                y += line_height;
            case '\r':
                if (max_x < x) max_x = x;
                x = x_start;

                draw_text_lines (pdc, pdc->pLogFont, origx, origy, x, y);
                origx = x; origy = y;

                gdi_start_new_line (pdc->pLogFont);
                break;

            case '\t':
                x += tab_width;
                gdi_start_new_line (pdc->pLogFont);
                break;

            default:
                put_one_char (pdc, pdc->pLogFont, sbc_devfont, &x, &y, 
                                        sbc_height, sbc_ascent, text, len_cur_char);
                x += pdc->cExtra;
                break;
            }
        else
            break;

       left_bytes -= len_cur_char;
       text += len_cur_char;
    }

    draw_text_lines (pdc, pdc->pLogFont, origx, origy, x, y);

    if (max_x < x) max_x = x;
    return max_x - x_start;
}

int gdi_width_one_char (LOGFONT* logfont, DEVFONT* devfont, const char* mchar, int len, int* x, int* y)
{
    int w;
    
    if (devfont->font_ops->get_char_bbox) {
        int oldx = *x;
        (*devfont->font_ops->get_char_bbox) (logfont, devfont,
                            mchar, len, NULL, NULL, NULL, NULL);
        (*devfont->font_ops->get_char_advance) (logfont, devfont, mchar, len, x, y);
        w = *x - oldx;
    }
    else
        w = (*devfont->font_ops->get_char_width) (logfont, devfont, mchar, len);
    
    if (logfont->style & FS_WEIGHT_BOLD 
        && !(devfont->style & FS_WEIGHT_BOLD)) {
        w ++;
    }

    return w;
}

void gdi_get_TextOut_extent (PDC pdc, LOGFONT* log_font, const char* text, int len, SIZE* size)
{
    DEVFONT* sbc_devfont = log_font->sbc_devfont;
    DEVFONT* mbc_devfont = log_font->mbc_devfont;
    int len_cur_char;
    int left_bytes = len;
    int x = 0, y = 0;
    
    gdi_start_new_line (log_font);

    /* FIXME: cy is not the height when rotate font */
    size->cy = log_font->size + pdc->alExtra + pdc->blExtra;
    size->cx = 0;
    while (left_bytes > 0) {
        if (mbc_devfont != NULL) {
            len_cur_char = (*mbc_devfont->charset_ops->len_first_char) (text, left_bytes);
            if (len_cur_char != 0) {
                size->cx += gdi_width_one_char (log_font, mbc_devfont, 
                    text, len_cur_char, &x, &y);
                size->cx += pdc->cExtra;
                left_bytes -= len_cur_char;
                text += len_cur_char;
                continue;
            }
        }

        len_cur_char = (*sbc_devfont->charset_ops->len_first_char) (text, left_bytes);
        if (len_cur_char != 0) {
            size->cx += gdi_width_one_char (log_font, sbc_devfont, 
                    text, len_cur_char, &x, &y);
            size->cx += pdc->cExtra;
        }
        else
            break;

        left_bytes -= len_cur_char;
        text += len_cur_char;
    }
}

void gdi_get_TabbedTextOut_extent (PDC pdc, LOGFONT* log_font, int tab_stops,
                const char* text, int len, SIZE* size, POINT* last_pos)
{
    DEVFONT* sbc_devfont = log_font->sbc_devfont;
    DEVFONT* mbc_devfont = log_font->mbc_devfont;
    int len_cur_char;
    int left_bytes = len;
    int tab_width, line_height;
    int last_line_width = 0;
    int x = 0, y = 0;

    gdi_start_new_line (log_font);

    size->cx = 0;
    size->cy = 0;
    tab_width = (*sbc_devfont->font_ops->get_ave_width) (log_font, sbc_devfont)
                    * tab_stops;
    line_height = log_font->size + pdc->alExtra + pdc->blExtra;

    while (left_bytes > 0) {
        if (mbc_devfont != NULL) {
            len_cur_char = (*mbc_devfont->charset_ops->len_first_char) (text, left_bytes);
            if (len_cur_char != 0) {
                last_line_width += gdi_width_one_char (log_font, mbc_devfont, 
                    text, len_cur_char, &x, &y);
                last_line_width += pdc->cExtra;
                left_bytes -= len_cur_char;
                text += len_cur_char;
                continue;
            }
        }

        len_cur_char = (*sbc_devfont->charset_ops->len_first_char) (text, left_bytes);
        if (len_cur_char != 0)
            switch (*text) {
            case '\n':
                size->cy += line_height;
            case '\r':
                if (last_line_width > size->cx)
                    size->cx = last_line_width;
                last_line_width = 0;
                gdi_start_new_line (log_font);
            break;

            case '\t':
                last_line_width += tab_width;
                gdi_start_new_line (log_font);
            break;

            default:
                last_line_width += gdi_width_one_char (log_font, sbc_devfont, 
                            text, len_cur_char, &x, &y);
                last_line_width += pdc->cExtra;
            }
        else
            break;

        left_bytes -= len_cur_char;
        text += len_cur_char;
    }

    if (last_line_width > size->cx)
        size->cx = last_line_width;

    if (last_pos) {
        last_pos->x += last_line_width;
        last_pos->y += size->cy - line_height;
    }
}

⌨️ 快捷键说明

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