JujuAdams / Scribble

Efficient, internationalized, multi-effects text renderer for GameMaker
https://www.jujuadams.com/Scribble/
MIT License
321 stars 47 forks source link

Proper "highlight" effect for regions #489

Open gl326 opened 10 months ago

gl326 commented 10 months ago

I love the idea of regions as added in newer scribble releases, and something I expected to be able to do with them was to highlight a region of text with a standard "highlight" effect, e.g. a colored background behind the region of text that's highlighted.

I was able to mostly create the effect I wanted with this addition to _scribble_class_element:

    static region_draw = function(_element_x, _element_y, _region_name, _color=c_black, _alpha = 1, _typist = undefined, _typist_characters_trigger = 0)
    {
        var _model        = __get_model(true);
        var _page         = _model.__pages_array[__page];
        var _region_array = _page.__region_array;

        var _i = array_length(_region_array);
        repeat(_i)
        {
            --_i;
            var _region = _region_array[_i];
            if _region.__name==_region_name{
                if !is_undefined(_typist){
                    var _typist_pos = _typist.get_position();
                    if _typist_pos<min(_region.__end_glyph, _region.__start_glyph+_typist_characters_trigger){
                        break;  
                    }
                }
                var _bbox_array = _region.__bbox_array;
                var _matrix = __update_matrix(_model, _element_x, _element_y);
                var _out_matrix = matrix_multiply(_matrix, matrix_get(matrix_world));
                var _in_color = draw_get_color(),
                    _in_alpha = draw_get_alpha();
                draw_set_color(_color);
                draw_set_alpha(_alpha);

                var _j = 0;
                repeat(array_length(_bbox_array))
                {
                    var _bbox = _bbox_array[_j];
                    var _p1 = matrix_transform_vertex(_out_matrix, _bbox.__x1, _bbox.__y1, 0);
                    var _p2 = matrix_transform_vertex(_out_matrix, _bbox.__x2, _bbox.__y2, 0);
                    draw_rectangle(_p1[0],_p1[1],_p2[0],_p2[1],false);
                    ++_j;
                }

                draw_set_color(_in_color);
                draw_set_alpha(_in_alpha);
                break;
            }

        }

        return self;
    }

It can take a typist() into account to draw the region as highlighted only if the typist has rendered the highlighted region. It would be even neater if it could draw the region partially as the typist moves through it but for my needs this works ok.

This seems like a good standard effect to have. If you want to communicate to players that a region of text is highlightable, or highlighted, this is what I think they'd recognize most easily rather than just changing the color of the text.

JujuAdams commented 10 months ago

Thanks for your thoughts, Greg. I think I'd want to do this as a separate draw call (or maybe many if the text is wrapped onto another line) behind the text using a nine-sliced sprite. This'd allow Scribble users to give some extra texture to their highlights.