📄 kdu_show.cpp
字号:
new_view_dims.size = size; if (view_centre_known) { new_view_dims.pos.x = image_dims.pos.x - (size.x / 2) + (int) floor(0.5 + image_dims.size.x*view_centre_x); new_view_dims.pos.y = image_dims.pos.y - (size.y / 2) + (int) floor(0.5 + image_dims.size.y*view_centre_y); view_centre_known = false; } if (new_view_dims.pos.x < image_dims.pos.x) new_view_dims.pos.x = image_dims.pos.x; if (new_view_dims.pos.y < image_dims.pos.y) new_view_dims.pos.y = image_dims.pos.y; kdu_coords view_lim = new_view_dims.pos + new_view_dims.size; kdu_coords image_lim = image_dims.pos + image_dims.size; if (view_lim.x > image_lim.x) new_view_dims.pos.x -= view_lim.x-image_lim.x; if (view_lim.y > image_lim.y) new_view_dims.pos.y -= view_lim.y-image_lim.y; new_view_dims &= image_dims; bool need_redraw = new_view_dims.pos != view_dims.pos; view_dims = new_view_dims; // Get preferred minimum dimensions for the new buffer region. size = view_dims.size; size.x += (size.x>>4)+100; // A small boundary minimizes impact of scrolling size.y += (size.y>>4)+100; // Make sure buffered region is no larger than image if (size.x > image_dims.size.x) size.x = image_dims.size.x; if (size.y > image_dims.size.y) size.y = image_dims.size.y; kdu_dims new_buffer_dims; new_buffer_dims.size = size; new_buffer_dims.pos = buffer_dims.pos; // Make sure the buffer region is contained within the image kdu_coords buffer_lim = new_buffer_dims.pos + new_buffer_dims.size; if (buffer_lim.x > image_lim.x) new_buffer_dims.pos.x -= buffer_lim.x-image_lim.x; if (buffer_lim.y > image_lim.y) new_buffer_dims.pos.y -= buffer_lim.y-image_lim.y; assert(new_buffer_dims == (new_buffer_dims & image_dims)); // See if the buffered region includes any new locations at all. if ((new_buffer_dims.pos != buffer_dims.pos) || (new_buffer_dims != (new_buffer_dims & buffer_dims)) || (view_dims != (view_dims & new_buffer_dims))) { // We will need to reshuffle or resize the buffer anyway, so might // as well get the best location for the buffer. new_buffer_dims.pos.x = view_dims.pos.x - (new_buffer_dims.size.x-view_dims.size.x) / 2; new_buffer_dims.pos.y = view_dims.pos.y - (new_buffer_dims.size.y-view_dims.size.y) / 2; if (new_buffer_dims.pos.x < image_dims.pos.x) new_buffer_dims.pos.x = image_dims.pos.x; if (new_buffer_dims.pos.y < image_dims.pos.y) new_buffer_dims.pos.y = image_dims.pos.y; buffer_lim = new_buffer_dims.pos + new_buffer_dims.size; if (buffer_lim.x > image_lim.x) new_buffer_dims.pos.x -= buffer_lim.x - image_lim.x; if (buffer_lim.y > image_lim.y) new_buffer_dims.pos.y -= buffer_lim.y - image_lim.y; assert(view_dims == (view_dims & new_buffer_dims)); assert(new_buffer_dims == (image_dims & new_buffer_dims)); assert(view_dims == (new_buffer_dims & view_dims)); } // Now deal with growth in the physical buffer size. kdu_coords new_buffer_extent = new_buffer_dims.size; if (new_buffer_extent.x < buffer_extent.x) new_buffer_extent.x = buffer_extent.x; // Physical buffer can only grow if (new_buffer_extent.y < buffer_extent.y) new_buffer_extent.y = buffer_extent.y; // Physical buffer can only grow new_buffer_extent.x += (4-new_buffer_extent.x) & 3; // Make multiple of 4. if (new_buffer_extent != buffer_extent) { kdu_byte *new_buffer = new kdu_byte[new_buffer_extent.x*new_buffer_extent.y*3]; kdu_byte *sp = buffer; kdu_byte *dp = new_buffer; for (int y=0; y < buffer_dims.size.y; y++, sp += buffer_extent.x*3, dp += new_buffer_extent.x*3) memcpy(dp,sp,(size_t)(buffer_dims.size.x*3)); buffer_extent = new_buffer_extent; delete[] buffer; buffer = new_buffer; } // Now deal with changes in the buffered region dimensions // We may grow the original buffer size first, as necessary and then check // for changes in position. int extra_cols = new_buffer_dims.size.x - buffer_dims.size.x; if (extra_cols > 0) { // Fill extra samples with a grey background. kdu_byte *spp = buffer; for (int y=0; y < buffer_dims.size.y; y++, spp+=buffer_extent.x*3) { kdu_byte *sp = spp + buffer_dims.size.x*3; for (int c=extra_cols; c > 0; c--) { *(sp++) = 128; *(sp++) = 128; *(sp++) = 128; } } buffer_dims.size.x = new_buffer_dims.size.x; } int extra_rows = new_buffer_dims.size.y - buffer_dims.size.y; if (extra_rows > 0) { // Fill extra samples rows with a grey background. kdu_byte *spp = buffer + (buffer_dims.size.y*buffer_extent.x*3); for (int r=extra_rows; r > 0; r--, spp += buffer_extent.x*3) { kdu_byte *sp = spp; for (int c=new_buffer_dims.size.x; c > 0; c--) { *(sp++) = 128; *(sp++) = 128; *(sp++) = 128; } } buffer_dims.size.y = new_buffer_dims.size.y; } update_buffer_pos(new_buffer_dims.pos); buffer_dims.size = new_buffer_dims.size; // In case the size shrunk // Now reflect changes in the view size to the appearance of scroll bars. SCROLLINFO sc_info; sc_info.cbSize = sizeof(sc_info); sc_info.fMask = SIF_DISABLENOSCROLL | SIF_ALL; sc_info.nMin = 0; sc_info.nMax = image_dims.size.x-1; sc_info.nPage = view_dims.size.x; sc_info.nPos = view_dims.pos.x - image_dims.pos.x; child->SetScrollInfo(SB_HORZ,&sc_info); sc_info.fMask = SIF_DISABLENOSCROLL | SIF_ALL; sc_info.nMin = 0; sc_info.nMax = image_dims.size.y-1; sc_info.nPage = view_dims.size.y; sc_info.nPos = view_dims.pos.y - image_dims.pos.y; child->SetScrollInfo(SB_VERT,&sc_info); kdu_coords step = view_dims.size; step.x = (step.x >> 4) + 1; step.y = (step.y >> 4) + 1; kdu_coords page = view_dims.size - step; child->set_scroll_metrics(step,page,image_dims.size-view_dims.size); // Finally, reflect any buffer changes into the valid data region. update_valid_region(); if (need_redraw) child->Invalidate(); child->UpdateWindow();}/******************************************************************************//* CKdu_showApp::set_hscroll_pos *//******************************************************************************/void CKdu_showApp::set_hscroll_pos(int pos, bool relative_to_last){ if (!codestream) return; view_centre_known = false; if (relative_to_last) pos += view_dims.pos.x; else pos += image_dims.pos.x; if (pos < image_dims.pos.x) pos = image_dims.pos.x; if ((pos+view_dims.size.x) > (image_dims.pos.x+image_dims.size.x)) pos = image_dims.pos.x+image_dims.size.x-view_dims.size.x; if (pos != view_dims.pos.x) { RECT update; child->ScrollWindowEx(view_dims.pos.x-pos,0,NULL,NULL,NULL,&update,0); view_dims.pos.x = pos; if (view_dims != (view_dims & buffer_dims)) { // The view is no longer fully contained in the buffered region. kdu_coords buf_pos = buffer_dims.pos; buf_pos.x = view_dims.pos.x - (buffer_dims.size.x-view_dims.size.x)/2; if (buf_pos.x < image_dims.pos.x) buf_pos.x = image_dims.pos.x; int image_lim = image_dims.pos.x+image_dims.size.x; int buf_lim = buf_pos.x + buffer_dims.size.x; if (buf_lim > image_lim) buf_pos.x -= (buf_lim-image_lim); update_buffer_pos(buf_pos); } // Repaint the erased area -- note that although the scroll function // is supposed to be able to invalidate the relevant regions of the // window, rendering this code unnecessary, that functionality appears // to be able to fail badly under certain extremely fast scrolling // sequences. Best to do the job ourselves. kdu_dims update_dims; update_dims.pos.x = update.left; update_dims.pos.y = update.top; update_dims.size.x = update.right-update.left; update_dims.size.y = update.bottom-update.top; CDC *dc = child->GetDC(); paint_region(dc,update_dims); child->ReleaseDC(dc); } child->SetScrollPos(SB_HORZ,pos-image_dims.pos.x);}/******************************************************************************//* CKdu_showApp::set_vscroll_pos *//******************************************************************************/void CKdu_showApp::set_vscroll_pos(int pos, bool relative_to_last){ if (!codestream) return; view_centre_known = false; if (relative_to_last) pos += view_dims.pos.y; else pos += image_dims.pos.y; if (pos < image_dims.pos.y) pos = image_dims.pos.y; if ((pos+view_dims.size.y) > (image_dims.pos.y+image_dims.size.y)) pos = image_dims.pos.y+image_dims.size.y-view_dims.size.y; if (pos != view_dims.pos.y) { RECT update; child->ScrollWindowEx(0,view_dims.pos.y-pos,NULL,NULL,NULL,&update,0); view_dims.pos.y = pos; if (view_dims != (view_dims & buffer_dims)) { // The view is no longer fully contained in the buffered region. kdu_coords buf_pos = buffer_dims.pos; buf_pos.y = view_dims.pos.y - (buffer_dims.size.y-view_dims.size.y)/2; if (buf_pos.y < image_dims.pos.y) buf_pos.y = image_dims.pos.y; int image_lim = image_dims.pos.y+image_dims.size.y; int buf_lim = buf_pos.y + buffer_dims.size.y; if (buf_lim > image_lim) buf_pos.y -= (buf_lim-image_lim); update_buffer_pos(buf_pos); } // Repaint the erased area -- note that although the scroll function // is supposed to be able to invalidate the relevant regions of the // window, rendering this code unnecessary, that functionality appears // to be able to fail badly under certain extremely fast scrolling // sequences. Best to do the job ourselves. kdu_dims update_dims; update_dims.pos.x = update.left; update_dims.pos.y = update.top; update_dims.size.x = update.right-update.left; update_dims.size.y = update.bottom-update.top; CDC *dc = child->GetDC(); paint_region(dc,update_dims); child->ReleaseDC(dc); } child->SetScrollPos(SB_VERT,pos-image_dims.pos.y);}/******************************************************************************//* CKdu_showApp::update_buffer_pos *//******************************************************************************/void CKdu_showApp::update_buffer_pos(kdu_coords pos){ if (pos.y < buffer_dims.pos.y) { // Shift buffered data down. int r, overlap_rows = buffer_dims.size.y + pos.y - buffer_dims.pos.y; if (overlap_rows < 0) overlap_rows = 0; kdu_byte *dp = buffer + (buffer_dims.size.y*buffer_extent.x*3); kdu_byte *sp = dp + (pos.y-buffer_dims.pos.y)*(buffer_extent.x*3); for (r=0; r < overlap_rows; r++) { sp -= buffer_extent.x*3; dp -= buffer_extent.x*3; memcpy(dp,sp,(size_t)(buffer_dims.size.x*3)); } for (; r < buffer_dims.size.y; r++) { dp -= buffer_extent.x*3; memset(dp,128,(size_t)(buffer_dims.size.x*3)); } buffer_dims.pos.y = pos.y; } else if (pos.y > buffer_dims.pos.y) { // Shift buffered data up. int r, overlap_rows = buffer_dims.size.y - pos.y + buffer_dims.pos.y; if (overlap_rows < 0) overlap_rows = 0; kdu_byte *dp = buffer; kdu_byte *sp = dp + (pos.y-buffer_dims.pos.y)*(buffer_extent.x*3); for (r=0; r < overlap_rows; r++) { memcpy(dp,sp,(size_t)(buffer_dims.size.x*3)); sp += buffer_extent.x*3; dp += buffer_extent.x*3; } for (; r < buffer_dims.size.y; r++) { memset(dp,128,(size_t)(buffer_dims.size.x*3)); dp += buffer_extent.x*3; } buffer_dims.pos.y = pos.y; } if (pos.x < buffer_dims.pos.x) { // Shift buffered data to the right. int r, c, overlap_cols = buffer_dims.size.x + pos.x - buffer_dims.pos.x; if (overlap_cols < 0) overlap_cols = 0; kdu_byte *dp = buffer + (buffer_dims.size.x*3); kdu_byte *sp = dp + (pos.x-buffer_dims.pos.x)*3; for (r=buffer_dims.size.y; r > 0; r--) { for (c=0; c < overlap_cols; c++) { *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); } for (; c < buffer_dims.size.x; c++, sp -= 3) { *(--dp) = 128; *(--dp) = 128; *(--dp) = 128; } sp += (buffer_extent.x+buffer_dims.size.x)*3; dp += (buffer_extent.x+buffer_dims.size.x)*3; } buffer_dims.pos.x = pos.x; } else if (pos.x > buffer_dims.pos.x) { // Shift buffered data to the left. int r, c, overlap_cols = buffer_dims.size.x - pos.x + buffer_dims.pos.x; if (overlap_cols < 0) overlap_cols = 0; kdu_byte *dp = buffer; kdu_byte *sp = dp + (pos.x-buffer_dims.pos.x)*3; for (r=buffer_extent.y; r > 0; r--) { for (c=0; c < overlap_cols; c++) { *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); } for (; c < buffer_dims.size.x; c++, sp+=3) { *(dp++) = 128; *(dp++) = 128; *(dp++) = 128; } sp += (buffer_extent.x-buffer_dims.size.x)*3; dp += (buffer_extent.x-buffer_dims.size.x)*3; } buffer_dims.pos.x = pos.x; } update_valid_region();}/******************************************************************************//* CKdu_showApp::update_valid_region *//******************************************************************************/void CKdu_showApp::update_valid_region(){ valid_dims &= buffer_dims; if (processing) { region_in_process &= buffer_dims; incomplete_region &= buffer_dims; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -