Example #1
0
 public ImColor(ImVec4 col)
 {
     Value = col;
 }
Example #2
0
        internal ImRect RenderText(float size, ImVec2 pos, uint col, ImVec4 clip_rect, char[] text, int text_begin, int text_end, ImDrawList draw_list, float wrap_width = 0.0f, bool cpu_fine_clip = false)
        {
            if (text_end == -1)
            {
                text_end = text.Length; // FIXME-OPT: Need to avoid this.
            }
            // Align to be pixel perfect
            pos.x = (int)pos.x + DisplayOffset.x;
            pos.y = (int)pos.y + DisplayOffset.y;
            float x = pos.x;
            float y = pos.y;

            if (y > clip_rect.w)
            {
                return(new ImRect());
            }

            float scale             = size / FontSize;
            float line_height       = FontSize * scale;
            bool  word_wrap_enabled = (wrap_width > 0.0f);
            int   word_wrap_eol     = -1;

            int  vtx_write       = draw_list._VtxWritePtr;
            int  idx_write       = draw_list._IdxWritePtr;
            uint vtx_current_idx = draw_list._VtxCurrentIdx;

            int s = text_begin;

            if (!word_wrap_enabled && y + line_height < clip_rect.y)
            {
                while (s < text_end && text[s] != '\n')  // Fast-forward to next line
                {
                    s++;
                }
            }

            while (s < text_end)
            {
                if (word_wrap_enabled)
                {
                    // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
                    if (word_wrap_eol != -1)
                    {
                        word_wrap_eol = CalcWordWrapPositionA(scale, text, s, text_end, wrap_width - (x - pos.x));
                        if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
                        {
                            word_wrap_eol++;    // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
                        }
                    }

                    if (s >= word_wrap_eol)
                    {
                        x             = pos.x;
                        y            += line_height;
                        word_wrap_eol = -1;

                        // Wrapping skips upcoming blanks
                        while (s < text_end)
                        {
                            char wc = text[s];
                            if (char.IsSeparator(wc))
                            {
                                s++;
                            }
                            else if (wc == '\n')
                            {
                                s++; break;
                            }
                            else
                            {
                                break;
                            }
                        }
                        continue;
                    }
                }

                // Decode and advance source
                char c = text[s++];
                //if (c< 0x80)
                //{
                // s += 1;
                //}
                //else
                //{
                // s += ImTextCharFromUtf8(&c, s, text_end);
                // if (c == 0)
                //  break;
                //}

                if (c < 32)
                {
                    if (c == '\n')
                    {
                        x  = pos.x;
                        y += line_height;

                        if (y > clip_rect.w)
                        {
                            break;
                        }
                        if (!word_wrap_enabled && y + line_height < clip_rect.y)
                        {
                            while (s < text_end && text[s] != '\n')  // Fast-forward to next line
                            {
                                s++;
                            }
                        }

                        continue;
                    }
                    if (c == '\r')
                    {
                        continue;
                    }
                }

                float char_width = 0.0f;
                Glyph glyph;
                if (FindGlyph(c, out glyph))
                {
                    char_width = glyph.XAdvance * scale;

                    // Arbitrarily assume that both space and tabs are empty glyphs as an optimization
                    if (c != ' ' && c != '\t')
                    {
                        // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w
                        float y1 = (float)(y + glyph.Y0 * scale);
                        float y2 = (float)(y + glyph.Y1 * scale);

                        float x1 = (float)(x + glyph.X0 * scale);
                        float x2 = (float)(x + glyph.X1 * scale);
                        if (x1 <= clip_rect.z && x2 >= clip_rect.x)
                        {
                            // Render a character
                            float u1 = glyph.U0;
                            float v1 = glyph.V0;
                            float u2 = glyph.U1;
                            float v2 = glyph.V1;

                            // CPU side clipping used to fit text in their frame when the frame is too small. Only does clipping for axis aligned quads.
                            if (cpu_fine_clip)
                            {
                                if (x1 < clip_rect.x)
                                {
                                    u1 = u1 + (1.0f - (x2 - clip_rect.x) / (x2 - x1)) * (u2 - u1);
                                    x1 = clip_rect.x;
                                }
                                if (y1 < clip_rect.y)
                                {
                                    v1 = v1 + (1.0f - (y2 - clip_rect.y) / (y2 - y1)) * (v2 - v1);
                                    y1 = clip_rect.y;
                                }
                                if (x2 > clip_rect.z)
                                {
                                    u2 = u1 + ((clip_rect.z - x1) / (x2 - x1)) * (u2 - u1);
                                    x2 = clip_rect.z;
                                }
                                if (y2 > clip_rect.w)
                                {
                                    v2 = v1 + ((clip_rect.w - y1) / (y2 - y1)) * (v2 - v1);
                                    y2 = clip_rect.w;
                                }
                                if (y1 >= y2)
                                {
                                    x += char_width;
                                    continue;
                                }
                            }

                            // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug build.
                            // Inlined here:
                            {
                                draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx); draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx + 1); draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx + 2);
                                draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx); draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx + 2); draw_list.IdxBuffer[idx_write++] = (ImDrawIdx)(vtx_current_idx + 3);
                                draw_list.VtxBuffer[vtx_write++] = new ImDrawVert()
                                {
                                    pos = new ImVec2(x1, y1), uv = new ImVec2(u1, v1), col = col
                                };
                                draw_list.VtxBuffer[vtx_write++] = new ImDrawVert()
                                {
                                    pos = new ImVec2(x2, y1), uv = new ImVec2(u2, v1), col = col
                                };
                                draw_list.VtxBuffer[vtx_write++] = new ImDrawVert()
                                {
                                    pos = new ImVec2(x2, y2), uv = new ImVec2(u2, v2), col = col
                                };
                                draw_list.VtxBuffer[vtx_write++] = new ImDrawVert()
                                {
                                    pos = new ImVec2(x1, y2), uv = new ImVec2(u1, v2), col = col
                                };
                                vtx_current_idx += 4;
                            }
                        }
                    }
                }

                x += char_width;
            }

            draw_list._VtxWritePtr   = vtx_write;
            draw_list._VtxCurrentIdx = vtx_current_idx;
            draw_list._IdxWritePtr   = idx_write;
            return(new ImRect(pos, new ImVec2(x, y + line_height)));
        }