예제 #1
0
파일: edit_main.cpp 프로젝트: xywei/texmacs
void
edit_main_rep::print (url name, bool conform, int first, int last) {
  bool ps  = (suffix (name) == "ps");
  bool pdf = (suffix (name) == "pdf");
  url  orig= resolve (name, "");

#ifdef USE_GS
  if (!use_pdf () && pdf)
    name= url_temp (".ps");
  if (!use_ps () && ps)
    name= url_temp (".pdf");
#endif
  
  string medium = env->get_string (PAGE_MEDIUM);
  if (conform && (medium != "paper")) conform= false;
  // FIXME: better command for conform printing

  // Set environment variables for printing

  typeset_prepare ();
  env->write (DPI, printing_dpi);
  env->write (PAGE_SHOW_HF, "true");
  env->write (PAGE_SCREEN_MARGIN, "false");
  if (!conform) {
    env->write (PAGE_MEDIUM, "paper");
    env->write (PAGE_PRINTED, "true");
  }

  // Typeset pages for printing

  box the_box= typeset_as_document (env, subtree (et, rp), reverse (rp));

  // Determine parameters for printer

  string page_type = env->get_string (PAGE_TYPE);
  double w         = env->page_width;
  double h         = env->page_height;
  double cm        = env->as_length (string ("1cm"));
  bool   landsc    = env->page_landscape;
  int    dpi       = as_int (printing_dpi);
  int    start     = max (0, first-1);
  int    end       = min (N(the_box[0]), last);
  int    pages     = end-start;
  if (conform) {
    page_type= "user";
    SI bw= the_box[0][0]->w();
    SI bh= the_box[0][0]->h();
    string bws= as_string (bw) * "tmpt";
    string bhs= as_string (bh) * "tmpt";
    w= env->as_length (bws);
    h= env->as_length (bhs);
  }

  // Print pages
  renderer ren;
#ifdef PDF_RENDERER
  if (use_pdf () && (pdf || !use_ps ()))
    ren= pdf_hummus_renderer (name, dpi, pages, page_type, landsc, w/cm, h/cm);
  else
    ren= printer (name, dpi, pages, page_type, landsc, w/cm, h/cm);
#else
  ren= printer (name, dpi, pages, page_type, landsc, w/cm, h/cm);
#endif
  
  if (ren->is_started ()) {
    int i;
    ren->set_metadata ("title", get_metadata ("title"));
    ren->set_metadata ("author", get_metadata ("author"));
    ren->set_metadata ("subject", get_metadata ("subject"));
    for (i=start; i<end; i++) {
      tree bg= env->read (BG_COLOR);
      ren->set_background (bg);
      if (bg != "white")
        ren->clear_pattern (0, (SI) -h, (SI) w, 0);

      rectangles rs;
      the_box[0]->sx(i)= 0;
      the_box[0]->sy(i)= 0;
      the_box[0][i]->redraw (ren, path (0), rs);
      if (i<end-1) ren->next_page ();
    }
  }
  tm_delete (ren);

#ifdef USE_GS
  if (!use_pdf () && pdf) {
    gs_to_pdf (name, orig, landsc, h/cm, w/cm);
    ::remove (name);
  }
  if (!use_ps () && ps) {
    gs_to_ps (name, orig, landsc, h/cm, w/cm);
    ::remove (name);
  }
  if (ps || pdf)
    if (get_preference ("texmacs->pdf:check", "off") == "on") {
      system_wait ("Checking exported file for correctness", "please wait");
      gs_check (orig);
    }
#endif
}
예제 #2
0
/* GL locking is done by the caller */
static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context *context,
        const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType,
        const void *idxData, UINT idxSize, UINT startIdx)
{
    unsigned int               textureNo    = 0;
    const WORD                *pIdxBufS     = NULL;
    const DWORD               *pIdxBufL     = NULL;
    UINT vx_index;
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    const UINT *streamOffset = This->stateBlock->streamOffset;
    long                      SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex;
    BOOL                      pixelShader = use_ps(This->stateBlock);
    BOOL specular_fog = FALSE;
    const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
    const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
    const struct wined3d_gl_info *gl_info = context->gl_info;
    UINT texture_stages = gl_info->limits.texture_stages;
    const struct wined3d_stream_info_element *element;
    UINT num_untracked_materials;
    DWORD tex_mask = 0;

    TRACE("Using slow vertex array code\n");

    /* Variable Initialization */
    if (idxSize != 0) {
        /* Immediate mode drawing can't make use of indices in a vbo - get the data from the index buffer.
         * If the index buffer has no vbo(not supported or other reason), or with user pointer drawing
         * idxData will be != NULL
         */
        if(idxData == NULL) {
            idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData);
        }

        if (idxSize == 2) pIdxBufS = idxData;
        else pIdxBufL = idxData;
    } else if (idxData) {
        ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
        return;
    }

    /* Start drawing in GL */
    glBegin(glPrimType);

    if (si->use_map & (1 << WINED3D_FFP_POSITION))
    {
        element = &si->elements[WINED3D_FFP_POSITION];
        position = element->data + streamOffset[element->stream_idx];
    }

    if (si->use_map & (1 << WINED3D_FFP_NORMAL))
    {
        element = &si->elements[WINED3D_FFP_NORMAL];
        normal = element->data + streamOffset[element->stream_idx];
    }
    else
    {
        glNormal3f(0, 0, 0);
    }

    num_untracked_materials = context->num_untracked_materials;
    if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
    {
        element = &si->elements[WINED3D_FFP_DIFFUSE];
        diffuse = element->data + streamOffset[element->stream_idx];

        if (num_untracked_materials && element->format_desc->format != WINED3DFMT_B8G8R8A8_UNORM)
            FIXME("Implement diffuse color tracking from %s\n", debug_d3dformat(element->format_desc->format));
    }
    else
    {
        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    }

    if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
    {
        element = &si->elements[WINED3D_FFP_SPECULAR];
        specular = element->data + streamOffset[element->stream_idx];

        /* special case where the fog density is stored in the specular alpha channel */
        if (This->stateBlock->renderState[WINED3DRS_FOGENABLE]
                && (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE
                    || si->elements[WINED3D_FFP_POSITION].format_desc->format == WINED3DFMT_R32G32B32A32_FLOAT)
                && This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
        {
            if (gl_info->supported[EXT_FOG_COORD])
            {
                if (element->format_desc->format == WINED3DFMT_B8G8R8A8_UNORM) specular_fog = TRUE;
                else FIXME("Implement fog coordinates from %s\n", debug_d3dformat(element->format_desc->format));
            }
            else
            {
                static BOOL warned;

                if (!warned)
                {
                    /* TODO: Use the fog table code from old ddraw */
                    FIXME("Implement fog for transformed vertices in software\n");
                    warned = TRUE;
                }
            }
        }
    }
    else if (gl_info->supported[EXT_SECONDARY_COLOR])
    {
        GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
    }

    for (textureNo = 0; textureNo < texture_stages; ++textureNo)
    {
        int coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
        DWORD texture_idx = This->texUnitMap[textureNo];

        if (!gl_info->supported[ARB_MULTITEXTURE] && textureNo > 0)
        {
            FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
            continue;
        }

        if (!pixelShader && !This->stateBlock->textures[textureNo]) continue;

        if (texture_idx == WINED3D_UNMAPPED_STAGE) continue;

        if (coordIdx > 7)
        {
            TRACE("tex: %d - Skip tex coords, as being system generated\n", textureNo);
            continue;
        }
        else if (coordIdx < 0)
        {
            FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx);
            continue;
        }

        if (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)))
        {
            element = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
            texCoords[coordIdx] = element->data + streamOffset[element->stream_idx];
            tex_mask |= (1 << textureNo);
        }
        else
        {
            TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
            if (gl_info->supported[ARB_MULTITEXTURE])
                GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
            else
                glTexCoord4f(0, 0, 0, 1);
        }
    }

    /* We shouldn't start this function if any VBO is involved. Should I put a safety check here?
     * Guess it's not necessary(we crash then anyway) and would only eat CPU time
     */

    /* For each primitive */
    for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {
        UINT texture, tmp_tex_mask;
        /* Blending data and Point sizes are not supported by this function. They are not supported by the fixed
         * function pipeline at all. A Fixme for them is printed after decoding the vertex declaration
         */

        /* For indexed data, we need to go a few more strides in */
        if (idxData != NULL) {

            /* Indexed so work out the number of strides to skip */
            if (idxSize == 2)
                SkipnStrides = pIdxBufS[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex;
            else
                SkipnStrides = pIdxBufL[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex;
        }

        tmp_tex_mask = tex_mask;
        for (texture = 0; tmp_tex_mask; tmp_tex_mask >>= 1, ++texture)
        {
            int coord_idx;
            const void *ptr;
            DWORD texture_idx;

            if (!(tmp_tex_mask & 1)) continue;

            coord_idx = This->stateBlock->textureState[texture][WINED3DTSS_TEXCOORDINDEX];
            ptr = texCoords[coord_idx] + (SkipnStrides * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride);

            texture_idx = This->texUnitMap[texture];
            multi_texcoord_funcs[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format_desc->emit_idx](
                    GL_TEXTURE0_ARB + texture_idx, ptr);
        }

        /* Diffuse -------------------------------- */
        if (diffuse) {
            const void *ptrToCoords = diffuse + SkipnStrides * si->elements[WINED3D_FFP_DIFFUSE].stride;

            diffuse_funcs[si->elements[WINED3D_FFP_DIFFUSE].format_desc->emit_idx](ptrToCoords);
            if (num_untracked_materials)
            {
                DWORD diffuseColor = ((const DWORD *)ptrToCoords)[0];
                unsigned char i;
                float color[4];

                color[0] = D3DCOLOR_B_R(diffuseColor) / 255.0f;
                color[1] = D3DCOLOR_B_G(diffuseColor) / 255.0f;
                color[2] = D3DCOLOR_B_B(diffuseColor) / 255.0f;
                color[3] = D3DCOLOR_B_A(diffuseColor) / 255.0f;

                for (i = 0; i < num_untracked_materials; ++i)
                {
                    glMaterialfv(GL_FRONT_AND_BACK, context->untracked_materials[i], color);
                }
            }
        }

        /* Specular ------------------------------- */
        if (specular) {
            const void *ptrToCoords = specular + SkipnStrides * si->elements[WINED3D_FFP_SPECULAR].stride;

            specular_funcs[si->elements[WINED3D_FFP_SPECULAR].format_desc->emit_idx](ptrToCoords);

            if (specular_fog)
            {
                DWORD specularColor = *(const DWORD *)ptrToCoords;
                GL_EXTCALL(glFogCoordfEXT(specularColor >> 24));
            }
        }

        /* Normal -------------------------------- */
        if (normal != NULL) {
            const void *ptrToCoords = normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride;
            normal_funcs[si->elements[WINED3D_FFP_NORMAL].format_desc->emit_idx](ptrToCoords);
        }

        /* Position -------------------------------- */
        if (position) {
            const void *ptrToCoords = position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride;
            position_funcs[si->elements[WINED3D_FFP_POSITION].format_desc->emit_idx](ptrToCoords);
        }

        /* For non indexed mode, step onto next parts */
        if (idxData == NULL) {
            ++SkipnStrides;
        }
    }

    glEnd();
    checkGLcall("glEnd and previous calls");
}