/* Updates DrawContext attr & drawCount. Return UR_OK/UR_THROW. */ int itemview_parse( DrawContext* dc, UThread* ut, UBlockIter* bi, GWidget* wp ) { const UCell* arg[3]; UAtom atom; int opcode; float x, y; while( bi->it != bi->end ) { if( ur_is(bi->it, UT_WORD) ) { atom = ur_atom( bi->it ); opcode = ur_atomsSearch( glEnv.drawOpTable, DOP_COUNT, atom ); switch( opcode ) { case DOP_IMAGE: { QuadDim qd; int16_t rect[4]; const int16_t* coord; FETCH_ARGS( iv_args_image ); //printf( "KR IV image\n" ); coord = arg[0]->coord.n; rect[0] = coord[0] + dc->penX; rect[1] = coord[1] + dc->penY; rect[2] = coord[2]; rect[3] = coord[3]; quad_init( &qd, rect, arg[1]->coord.n, arg[2]->coord.n ); quad_emitVT( &qd, dc->attr, dc->attr + 3, AttrCount ); vbo_setVec3( dc->attr + 5, AttrCount, 6, dc->color ); dc->attr += 6 * AttrCount; dc->drawCount += 6; } break; case DOP_COLOR: FETCH_ARGS( iv_args_color ); dc->color[0] = (GLfloat) ur_int( arg[0] ); break; case DOP_FONT: FETCH_ARGS( iv_args_font ); dc->fontN = ur_fontTF( arg[0] ); break; case DOP_TEXT: FETCH_ARGS( iv_args_text ); x = dc->penX + (float) arg[0]->coord.n[0]; y = dc->penY + (float) arg[0]->coord.n[1]; { DrawTextState dts; UBinaryIter si; int glyphCount; //printf( "KR IV text\n" ); dp_toString( ut, arg[1], &si ); vbo_drawTextInit( &dts, (TexFont*) ur_buffer( dc->fontN )->ptr.v, x, y ); dts.emitTris = 1; glyphCount = vbo_drawText( &dts, dc->attr + 3, dc->attr, AttrCount, si.it, si.end ); glyphCount *= 6; vbo_setVec3( dc->attr + 5, AttrCount, glyphCount, dc->color ); /* while( si.it != si.end ) putchar( *si.it++ ); putchar( '\n' ); */ dc->attr += glyphCount * AttrCount; dc->drawCount += glyphCount; } break; default: goto invalid_op; } } else { goto invalid_op; } } return UR_OK; invalid_op: return ur_error( ut, UR_ERR_SCRIPT, "Invalid item-view instruction" ); }
static void ledit_render( GWidget* wp ) { DrawTextState ds; GLuint* buf; GLfloat* fdata; UBuffer* str; TexFont* tf; UCell* style = glEnv.guiStyle; UThread* ut = glEnv.guiUT; EX_PTR; if( ! ep->strN ) return; tf = ur_texFontV( ut, style + CI_STYLE_EDIT_FONT ); if( tf ) { str = ur_buffer( ep->strN ); buf = vbo_bufIds( ur_buffer(ep->vboN) ); if( flagged( NEW_CURSORX ) ) { int pos; clrFlag( NEW_CURSORX ); pos = txf_charAtPixel( tf, str->ptr.b, str->ptr.b + str->used, ep->newCursorX - wp->area.x - MARGIN_L ); if( pos < 0 ) pos = (ep->newCursorX > wp->area.x + MARGIN_L) ? str->used : 0; if( pos != ep->editPos ) { ep->editPos = pos; setFlag( CHANGED ); } } #ifndef GL_ES_VERSION_2_0 glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glBindBuffer( GL_ARRAY_BUFFER, buf[0] ); if( flagged( CHANGED ) ) { clrFlag( CHANGED ); fdata = (float*) glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); if( fdata ) { // Cursor verticies. int xpos = txf_width(tf, str->ptr.b, str->ptr.b + ep->editPos ); // FIXME: UVs require black pixels at upper-left of texture. fdata[0] = 0.003f; fdata[1] = 0.0f; //95f; fdata[2] = (GLfloat) (wp->area.x + xpos + MARGIN_L); fdata[3] = (GLfloat) wp->area.y; fdata[4] = 0.003f; fdata[5] = 0.01f; //998f; fdata[6] = fdata[2]; fdata[7] = fdata[3] + txf_lineSpacing( tf ); //glBufferSubData(GL_ARRAY_BUFFER, 0, LEDIT_ATTR_SIZE*2, data); fdata += LEDIT_APV * 2; vbo_drawTextInit( &ds, tf, wp->area.x + MARGIN_L, wp->area.y + MARGIN_B ); ep->drawn = 6 * vbo_drawText( &ds, fdata, fdata + 2, LEDIT_APV, str->ptr.b, str->ptr.b + str->used ); glUnmapBuffer( GL_ARRAY_BUFFER ); } //printf( "KR ledit draw\n" ); } glTexCoordPointer( 2, GL_FLOAT, LEDIT_ATTR_SIZE, NULL + 0 ); glVertexPointer ( 2, GL_FLOAT, LEDIT_ATTR_SIZE, NULL + 8 ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buf[1] ); glColor4f( 0.0, 0.0, 0.0, 1.0 ); glDrawElements( GL_TRIANGLES, ep->drawn, GL_UNSIGNED_SHORT, NULL + 4 ); if( gui_hasFocus( wp ) & GW_FOCUS_KEY ) glDrawElements( GL_LINES, 2, GL_UNSIGNED_SHORT, 0 ); glDisableClientState( GL_TEXTURE_COORD_ARRAY ); #endif } }