Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-06-11 12:55:40 +0300
committerJulian Eisel <julian@blender.org>2020-06-11 12:55:40 +0300
commit15e6f9012c84c4ebce41bf1928635a3abe046a55 (patch)
treedfc33ab9de451f2f510ff09eadf8b6eb6fdbf19f /source/blender
parent0b6def7059b6a64b3cef3ba7d4fa46000aee1761 (diff)
parent95aa8ffed56e7bd1784bab64e82c82c4e855ae48 (diff)
Merge branch 'master' into asset-uuid
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenlib/BLI_hash_tables.hh1
-rw-r--r--source/blender/blenlib/BLI_map.hh31
-rw-r--r--source/blender/blenlib/BLI_set.hh2
-rw-r--r--source/blender/blenlib/BLI_vector_set.hh4
-rw-r--r--source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp15
-rw-r--r--source/blender/editors/include/UI_interface.h4
-rw-r--r--source/blender/editors/interface/interface_handlers.c14
-rw-r--r--source/blender/editors/interface/interface_layout.c5
-rw-r--r--source/blender/editors/interface/interface_template_search_menu.c28
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c10
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c386
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h23
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c14
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c356
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h2
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp6
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_menu_type.c5
18 files changed, 472 insertions, 435 deletions
diff --git a/source/blender/blenlib/BLI_hash_tables.hh b/source/blender/blenlib/BLI_hash_tables.hh
index b565b396a7a..c3b0b1f90e0 100644
--- a/source/blender/blenlib/BLI_hash_tables.hh
+++ b/source/blender/blenlib/BLI_hash_tables.hh
@@ -30,6 +30,7 @@
#include "BLI_math_base.h"
#include "BLI_memory_utils.hh"
#include "BLI_string.h"
+#include "BLI_string_ref.hh"
#include "BLI_utildefines.h"
#include "BLI_vector.hh"
diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh
index 9737367ebca..4fc9f98d835 100644
--- a/source/blender/blenlib/BLI_map.hh
+++ b/source/blender/blenlib/BLI_map.hh
@@ -745,6 +745,21 @@ class Map {
}
};
+ struct Item {
+ const Key &key;
+ const Value &value;
+ };
+
+ struct MutableItem {
+ const Key &key;
+ Value &value;
+
+ operator Item() const
+ {
+ return Item{key, value};
+ }
+ };
+
class ItemIterator final : public BaseIterator<ItemIterator> {
public:
ItemIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
@@ -752,11 +767,6 @@ class Map {
{
}
- struct Item {
- const Key &key;
- const Value &value;
- };
-
Item operator*() const
{
const Slot &slot = this->current_slot();
@@ -771,12 +781,7 @@ class Map {
{
}
- struct Item {
- const Key &key;
- Value &value;
- };
-
- Item operator*() const
+ MutableItem operator*() const
{
Slot &slot = this->current_slot();
return {*slot.key(), *slot.value()};
@@ -838,7 +843,7 @@ class Map {
void print_stats(StringRef name = "") const
{
HashTableStats stats(*this, this->keys());
- stats.print();
+ stats.print(name);
}
/**
@@ -889,7 +894,7 @@ class Map {
*/
uint32_t size_in_bytes() const
{
- return sizeof(Slot) * m_slots.size();
+ return (uint32_t)(sizeof(Slot) * m_slots.size());
}
/**
diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh
index ece9fb05d8c..af0c3424f5a 100644
--- a/source/blender/blenlib/BLI_set.hh
+++ b/source/blender/blenlib/BLI_set.hh
@@ -410,7 +410,7 @@ class Set {
void print_stats(StringRef name = "") const
{
HashTableStats stats(*this, *this);
- stats.print();
+ stats.print(name);
}
/**
diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh
index d330d3c3247..dcd4927aed2 100644
--- a/source/blender/blenlib/BLI_vector_set.hh
+++ b/source/blender/blenlib/BLI_vector_set.hh
@@ -433,7 +433,7 @@ class VectorSet {
void print_stats(StringRef name = "") const
{
HashTableStats stats(*this, this->as_span());
- stats.print();
+ stats.print(name);
}
/**
@@ -482,7 +482,7 @@ class VectorSet {
*/
uint32_t size_in_bytes() const
{
- return sizeof(Slot) * m_slots.size() + sizeof(Key) * m_usable_slots;
+ return (uint32_t)(sizeof(Slot) * m_slots.size() + sizeof(Key) * m_usable_slots);
}
/**
diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp
index 39ffb690328..893c052831c 100644
--- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp
+++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp
@@ -38,6 +38,15 @@ void ColorCorrectionOperation::initExecution()
this->m_inputMask = this->getInputSocketReader(1);
}
+/* Calculate x^y if the function is defined. Otherwise return the given fallback value. */
+BLI_INLINE float color_correct_powf_safe(const float x, const float y, const float fallback_value)
+{
+ if (x < 0) {
+ return fallback_value;
+ }
+ return powf(x, y);
+}
+
void ColorCorrectionOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -116,9 +125,9 @@ void ColorCorrectionOperation::executePixelSampled(float output[4],
b = 0.5f + ((b - 0.5f) * contrast);
/* Check for negative values to avoid nan. */
- r = (r > 0.0f) ? powf(r * gain + lift, invgamma) : r;
- g = (g > 0.0f) ? powf(g * gain + lift, invgamma) : g;
- b = (b > 0.0f) ? powf(b * gain + lift, invgamma) : b;
+ r = color_correct_powf_safe(r * gain + lift, invgamma, r);
+ g = color_correct_powf_safe(g * gain + lift, invgamma, g);
+ b = color_correct_powf_safe(b * gain + lift, invgamma, b);
// mix with mask
r = mvalue * inputImageColor[0] + value * r;
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 11dbb105072..59dcc9a8ace 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -764,6 +764,7 @@ bool UI_but_online_manual_id(const uiBut *but,
bool UI_but_online_manual_id_from_active(const struct bContext *C,
char *r_str,
size_t maxlength) ATTR_WARN_UNUSED_RESULT;
+bool UI_but_is_userdef(const uiBut *but);
/* Buttons
*
@@ -2445,7 +2446,8 @@ void UI_context_update_anim_flag(const struct bContext *C);
void UI_context_active_but_prop_get_filebrowser(const struct bContext *C,
struct PointerRNA *r_ptr,
struct PropertyRNA **r_prop,
- bool *r_is_undo);
+ bool *r_is_undo,
+ bool *r_is_userdef);
void UI_context_active_but_prop_get_templateID(struct bContext *C,
struct PointerRNA *r_ptr,
struct PropertyRNA **r_prop);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b37b2f2cd4b..336f942ad8c 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -585,7 +585,7 @@ static bool ui_but_dragedit_update_mval(uiHandleButtonData *data, int mx)
return true;
}
-static void ui_rna_update_preferences_dirty(PointerRNA *ptr, PropertyRNA *prop)
+static bool ui_rna_is_userdef(PointerRNA *ptr, PropertyRNA *prop)
{
/* Not very elegant, but ensures preference changes force re-save. */
bool tag = false;
@@ -598,8 +598,18 @@ static void ui_rna_update_preferences_dirty(PointerRNA *ptr, PropertyRNA *prop)
tag = true;
}
}
+ return tag;
+}
- if (tag) {
+bool UI_but_is_userdef(const uiBut *but)
+{
+ /* This is read-only, RNA API isn't using const when it could. */
+ return ui_rna_is_userdef((PointerRNA *)&but->rnapoin, but->rnaprop);
+}
+
+static void ui_rna_update_preferences_dirty(PointerRNA *ptr, PropertyRNA *prop)
+{
+ if (ui_rna_is_userdef(ptr, prop)) {
U.runtime.is_dirty = true;
WM_main_add_notifier(NC_WINDOW, NULL);
}
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 196fdf47bd3..6aefef197df 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1069,7 +1069,8 @@ static uiBut *ui_item_with_label(uiLayout *layout,
void UI_context_active_but_prop_get_filebrowser(const bContext *C,
PointerRNA *r_ptr,
PropertyRNA **r_prop,
- bool *r_is_undo)
+ bool *r_is_undo,
+ bool *r_is_userdef)
{
ARegion *region = CTX_wm_menu(C) ? CTX_wm_menu(C) : CTX_wm_region(C);
uiBlock *block;
@@ -1078,6 +1079,7 @@ void UI_context_active_but_prop_get_filebrowser(const bContext *C,
memset(r_ptr, 0, sizeof(*r_ptr));
*r_prop = NULL;
*r_is_undo = false;
+ *r_is_userdef = false;
if (!region) {
return;
@@ -1096,6 +1098,7 @@ void UI_context_active_but_prop_get_filebrowser(const bContext *C,
*r_ptr = prevbut->rnapoin;
*r_prop = prevbut->rnaprop;
*r_is_undo = (prevbut->flag & UI_BUT_UNDO) != 0;
+ *r_is_userdef = UI_but_is_userdef(prevbut);
return;
}
}
diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index 2c6b09168f4..8c673e4d5b5 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -469,6 +469,34 @@ static struct MenuSearch_Data *menu_items_from_ui_create(
}
}
+ {
+ /* Exclude context menus because:
+ * - The menu items are available elsewhere (and will show up multiple times).
+ * - Menu items depend on exact context, making search results unpredictable
+ * (exact number of items selected for example). See design doc T74158.
+ * There is one exception,
+ * as the outliner only exposes functionality via the context menu. */
+ GHashIterator iter;
+
+ for (WM_menutype_iter(&iter); (!BLI_ghashIterator_done(&iter));
+ (BLI_ghashIterator_step(&iter))) {
+ MenuType *mt = BLI_ghashIterator_getValue(&iter);
+ if (BLI_str_endswith(mt->idname, "_context_menu")) {
+ BLI_gset_add(menu_tagged, mt);
+ }
+ }
+ const char *idname_array[] = {
+ /* Add back some context menus. */
+ "OUTLINER_MT_context_menu",
+ };
+ for (int i = 0; i < ARRAY_SIZE(idname_array); i++) {
+ MenuType *mt = WM_menutype_find(idname_array[i], false);
+ if (mt != NULL) {
+ BLI_gset_remove(menu_tagged, mt, NULL);
+ }
+ }
+ }
+
/* Collect contexts, one for each 'ui_type'. */
struct MenuSearch_Context *wm_contexts = NULL;
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 9af623d8065..53a904438eb 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -83,6 +83,7 @@ typedef struct FileBrowseOp {
PointerRNA ptr;
PropertyRNA *prop;
bool is_undo;
+ bool is_userdef;
} FileBrowseOp;
static int file_browse_exec(bContext *C, wmOperator *op)
@@ -148,6 +149,11 @@ static int file_browse_exec(bContext *C, wmOperator *op)
}
}
+ /* Tag user preferences as dirty. */
+ if (fbo->is_userdef) {
+ U.runtime.is_dirty = true;
+ }
+
MEM_freeN(op->customdata);
return OPERATOR_FINISHED;
@@ -164,6 +170,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
PointerRNA ptr;
PropertyRNA *prop;
bool is_undo;
+ bool is_userdef;
FileBrowseOp *fbo;
char *str;
@@ -172,7 +179,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
- UI_context_active_but_prop_get_filebrowser(C, &ptr, &prop, &is_undo);
+ UI_context_active_but_prop_get_filebrowser(C, &ptr, &prop, &is_undo, &is_userdef);
if (!prop) {
return OPERATOR_CANCELLED;
@@ -209,6 +216,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
fbo->ptr = ptr;
fbo->prop = prop;
fbo->is_undo = is_undo;
+ fbo->is_userdef = is_userdef;
op->customdata = fbo;
/* normally ED_fileselect_get_params would handle this but we need to because of stupid
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 28ded81eeae..aa2d5b2ae7d 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -50,17 +50,12 @@
#include "WM_types.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
/* For menu, popup, icons, etc. */
-
-#include "ED_anim_api.h"
#include "ED_numinput.h"
#include "ED_outliner.h"
#include "ED_screen.h"
#include "ED_sequencer.h"
-#include "ED_space_api.h"
-#include "ED_transform.h"
#include "UI_interface.h"
#include "UI_view2d.h"
@@ -2323,6 +2318,11 @@ void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot)
/** \name Split Strips Operator
* \{ */
+enum {
+ SEQ_SPLIT_SOFT,
+ SEQ_SPLIT_HARD,
+};
+
static const EnumPropertyItem prop_split_types[] = {
{SEQ_SPLIT_SOFT, "SOFT", 0, "Soft", ""},
{SEQ_SPLIT_HARD, "HARD", 0, "Hard", ""},
@@ -3092,321 +3092,6 @@ void SEQUENCER_OT_meta_separate(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Sequencer Frame All Operator
- * \{ */
-
-static int sequencer_view_all_exec(bContext *C, wmOperator *op)
-{
- ARegion *region = CTX_wm_region(C);
- rctf box;
-
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
- boundbox_seq(CTX_data_scene(C), &box);
- UI_view2d_smooth_view(C, region, &box, smooth_viewtx);
- return OPERATOR_FINISHED;
-}
-
-void SEQUENCER_OT_view_all(wmOperatorType *ot)
-{
- /* Identifiers. */
- ot->name = "Frame All";
- ot->idname = "SEQUENCER_OT_view_all";
- ot->description = "View all the strips in the sequencer";
-
- /* Api callbacks. */
- ot->exec = sequencer_view_all_exec;
- ot->poll = ED_operator_sequencer_active;
-
- /* Flags. */
- ot->flag = OPTYPE_REGISTER;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Go to Current Frame Operator
- * \{ */
-
-static int sequencer_view_frame_exec(bContext *C, wmOperator *op)
-{
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- ANIM_center_frame(C, smooth_viewtx);
-
- return OPERATOR_FINISHED;
-}
-
-void SEQUENCER_OT_view_frame(wmOperatorType *ot)
-{
- /* Identifiers. */
- ot->name = "Go to Current Frame";
- ot->idname = "SEQUENCER_OT_view_frame";
- ot->description = "Move the view to the current frame";
-
- /* Api callbacks. */
- ot->exec = sequencer_view_frame_exec;
- ot->poll = ED_operator_sequencer_active;
-
- /* Flags. */
- ot->flag = 0;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Preview Frame All Operator
- * \{ */
-
-static int sequencer_view_all_preview_exec(bContext *C, wmOperator *UNUSED(op))
-{
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *area = CTX_wm_area(C);
-#if 0
- ARegion *region = CTX_wm_region(C);
- SpaceSeq *sseq = area->spacedata.first;
- Scene *scene = CTX_data_scene(C);
-#endif
- View2D *v2d = UI_view2d_fromcontext(C);
-
- v2d->cur = v2d->tot;
- UI_view2d_curRect_validate(v2d);
- UI_view2d_sync(screen, area, v2d, V2D_LOCK_COPY);
-
-#if 0
- /* Like zooming on an image view. */
- float zoomX, zoomY;
- int width, height, imgwidth, imgheight;
-
- width = region->winx;
- height = region->winy;
-
- seq_reset_imageofs(sseq);
-
- imgwidth = (scene->r.size * scene->r.xsch) / 100;
- imgheight = (scene->r.size * scene->r.ysch) / 100;
-
- /* Apply aspect, doesn't need to be that accurate. */
- imgwidth = (int)(imgwidth * (scene->r.xasp / scene->r.yasp));
-
- if (((imgwidth >= width) || (imgheight >= height)) && ((width > 0) && (height > 0))) {
- /* Find the zoom value that will fit the image in the image space. */
- zoomX = ((float)width) / ((float)imgwidth);
- zoomY = ((float)height) / ((float)imgheight);
- sseq->zoom = (zoomX < zoomY) ? zoomX : zoomY;
-
- sseq->zoom = 1.0f / power_of_2(1 / min_ff(zoomX, zoomY));
- }
- else {
- sseq->zoom = 1.0f;
- }
-#endif
-
- ED_area_tag_redraw(CTX_wm_area(C));
- return OPERATOR_FINISHED;
-}
-
-void SEQUENCER_OT_view_all_preview(wmOperatorType *ot)
-{
- /* Identifiers. */
- ot->name = "Frame All";
- ot->idname = "SEQUENCER_OT_view_all_preview";
- ot->description = "Zoom preview to fit in the area";
-
- /* Api callbacks. */
- ot->exec = sequencer_view_all_preview_exec;
- ot->poll = ED_operator_sequencer_active;
-
- /* Flags. */
- ot->flag = OPTYPE_REGISTER;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Sequencer View Zoom Ratio Operator
- * \{ */
-
-static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
-{
- RenderData *rd = &CTX_data_scene(C)->r;
- View2D *v2d = UI_view2d_fromcontext(C);
-
- float ratio = RNA_float_get(op->ptr, "ratio");
-
- float winx = (int)(rd->size * rd->xsch) / 100;
- float winy = (int)(rd->size * rd->ysch) / 100;
-
- float facx = BLI_rcti_size_x(&v2d->mask) / winx;
- float facy = BLI_rcti_size_y(&v2d->mask) / winy;
-
- BLI_rctf_resize(&v2d->cur, ceilf(winx * facx / ratio + 0.5f), ceilf(winy * facy / ratio + 0.5f));
-
- ED_region_tag_redraw(CTX_wm_region(C));
-
- return OPERATOR_FINISHED;
-}
-
-void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot)
-{
- /* Identifiers. */
- ot->name = "Sequencer View Zoom Ratio";
- ot->idname = "SEQUENCER_OT_view_zoom_ratio";
- ot->description = "Change zoom ratio of sequencer preview";
-
- /* Api callbacks. */
- ot->exec = sequencer_view_zoom_ratio_exec;
- ot->poll = ED_operator_sequencer_active;
-
- /* Properties. */
- RNA_def_float(ot->srna,
- "ratio",
- 1.0f,
- -FLT_MAX,
- FLT_MAX,
- "Ratio",
- "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out",
- -FLT_MAX,
- FLT_MAX);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name View Toggle Operator
- * \{ */
-
-#if 0
-static const EnumPropertyItem view_type_items[] = {
- {SEQ_VIEW_SEQUENCE, "SEQUENCER", ICON_SEQ_SEQUENCER, "Sequencer", ""},
- {SEQ_VIEW_PREVIEW, "PREVIEW", ICON_SEQ_PREVIEW, "Image Preview", ""},
- {SEQ_VIEW_SEQUENCE_PREVIEW,
- "SEQUENCER_PREVIEW",
- ICON_SEQ_SEQUENCER,
- "Sequencer and Image Preview",
- ""},
- {0, NULL, 0, NULL, NULL},
-};
-#endif
-
-static int sequencer_view_toggle_exec(bContext *C, wmOperator *UNUSED(op))
-{
- SpaceSeq *sseq = (SpaceSeq *)CTX_wm_space_data(C);
-
- sseq->view++;
- if (sseq->view > SEQ_VIEW_SEQUENCE_PREVIEW) {
- sseq->view = SEQ_VIEW_SEQUENCE;
- }
-
- ED_area_tag_refresh(CTX_wm_area(C));
-
- return OPERATOR_FINISHED;
-}
-
-void SEQUENCER_OT_view_toggle(wmOperatorType *ot)
-{
- /* Identifiers. */
- ot->name = "View Toggle";
- ot->idname = "SEQUENCER_OT_view_toggle";
- ot->description = "Toggle between sequencer views (sequence, preview, both)";
-
- /* Api callbacks. */
- ot->exec = sequencer_view_toggle_exec;
- ot->poll = ED_operator_sequencer_active;
-
- /* Flags. */
- ot->flag = OPTYPE_REGISTER;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Frame Selected Operator
- * \{ */
-
-static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
-{
- Scene *scene = CTX_data_scene(C);
- View2D *v2d = UI_view2d_fromcontext(C);
- ARegion *region = CTX_wm_region(C);
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- Sequence *last_seq = BKE_sequencer_active_get(scene);
- Sequence *seq;
- rctf cur_new = v2d->cur;
-
- int xmin = MAXFRAME * 2;
- int xmax = -MAXFRAME * 2;
- int ymin = MAXSEQ + 1;
- int ymax = 0;
- int orig_height;
- int ymid;
- int ymargin = 1;
- int xmargin = FPS;
-
- if (ed == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if ((seq->flag & SELECT) || (seq == last_seq)) {
- xmin = min_ii(xmin, seq->startdisp);
- xmax = max_ii(xmax, seq->enddisp);
-
- ymin = min_ii(ymin, seq->machine);
- ymax = max_ii(ymax, seq->machine);
- }
- }
-
- if (ymax != 0) {
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
- xmax += xmargin;
- xmin -= xmargin;
- ymax += ymargin;
- ymin -= ymargin;
-
- orig_height = BLI_rctf_size_y(&cur_new);
-
- cur_new.xmin = xmin;
- cur_new.xmax = xmax;
-
- cur_new.ymin = ymin;
- cur_new.ymax = ymax;
-
- /* Only zoom out vertically. */
- if (orig_height > BLI_rctf_size_y(&cur_new)) {
- ymid = BLI_rctf_cent_y(&cur_new);
-
- cur_new.ymin = ymid - (orig_height / 2);
- cur_new.ymax = ymid + (orig_height / 2);
- }
-
- UI_view2d_smooth_view(C, region, &cur_new, smooth_viewtx);
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
-}
-
-void SEQUENCER_OT_view_selected(wmOperatorType *ot)
-{
- /* Identifiers. */
- ot->name = "Frame Selected";
- ot->idname = "SEQUENCER_OT_view_selected";
- ot->description = "Zoom the sequencer on the selected strips";
-
- /* Api callbacks. */
- ot->exec = sequencer_view_selected_exec;
- ot->poll = ED_operator_sequencer_active;
-
- /* Flags. */
- ot->flag = OPTYPE_REGISTER;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Jump to Strip Operator
* \{ */
@@ -3857,67 +3542,6 @@ void SEQUENCER_OT_swap_data(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Border Offset View Operator
- * \{ */
-
-static int view_ghost_border_exec(bContext *C, wmOperator *op)
-{
- Scene *scene = CTX_data_scene(C);
- View2D *v2d = UI_view2d_fromcontext(C);
-
- rctf rect;
-
- /* Convert coordinates of rect to 'tot' rect coordinates. */
- WM_operator_properties_border_to_rctf(op, &rect);
- UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
-
- rect.xmin /= fabsf(BLI_rctf_size_x(&v2d->tot));
- rect.ymin /= fabsf(BLI_rctf_size_y(&v2d->tot));
-
- rect.xmax /= fabsf(BLI_rctf_size_x(&v2d->tot));
- rect.ymax /= fabsf(BLI_rctf_size_y(&v2d->tot));
-
- rect.xmin += 0.5f;
- rect.xmax += 0.5f;
- rect.ymin += 0.5f;
- rect.ymax += 0.5f;
-
- CLAMP(rect.xmin, 0.0f, 1.0f);
- CLAMP(rect.ymin, 0.0f, 1.0f);
- CLAMP(rect.xmax, 0.0f, 1.0f);
- CLAMP(rect.ymax, 0.0f, 1.0f);
-
- scene->ed->over_border = rect;
-
- WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
- return OPERATOR_FINISHED;
-}
-
-void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
-{
- /* Identifiers. */
- ot->name = "Border Offset View";
- ot->idname = "SEQUENCER_OT_view_ghost_border";
- ot->description = "Set the boundaries of the border used for offset-view";
-
- /* Api callbacks. */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = view_ghost_border_exec;
- ot->modal = WM_gesture_box_modal;
- ot->poll = sequencer_view_preview_poll;
- ot->cancel = WM_gesture_box_cancel;
-
- /* Flags. */
- ot->flag = 0;
-
- /* Properties. */
- WM_operator_properties_gesture_box(ot);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Rebuild Proxy and Timecode Indices Operator
* \{ */
diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h
index eec8d604b64..12533dbc74f 100644
--- a/source/blender/editors/space_sequencer/sequencer_intern.h
+++ b/source/blender/editors/space_sequencer/sequencer_intern.h
@@ -131,13 +131,6 @@ void SEQUENCER_OT_swap(struct wmOperatorType *ot);
void SEQUENCER_OT_swap_data(struct wmOperatorType *ot);
void SEQUENCER_OT_rendersize(struct wmOperatorType *ot);
-void SEQUENCER_OT_view_toggle(struct wmOperatorType *ot);
-void SEQUENCER_OT_view_all(struct wmOperatorType *ot);
-void SEQUENCER_OT_view_selected(struct wmOperatorType *ot);
-void SEQUENCER_OT_view_frame(struct wmOperatorType *ot);
-void SEQUENCER_OT_view_zoom_ratio(struct wmOperatorType *ot);
-void SEQUENCER_OT_view_ghost_border(struct wmOperatorType *ot);
-
void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot);
void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot);
void SEQUENCER_OT_change_path(struct wmOperatorType *ot);
@@ -152,9 +145,6 @@ void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot);
void SEQUENCER_OT_set_range_to_strips(struct wmOperatorType *ot);
-/* Preview specific operators. */
-void SEQUENCER_OT_view_all_preview(struct wmOperatorType *ot);
-
/* sequencer_select.c */
void SEQUENCER_OT_select_all(struct wmOperatorType *ot);
void SEQUENCER_OT_select(struct wmOperatorType *ot);
@@ -169,7 +159,7 @@ void SEQUENCER_OT_select_box(struct wmOperatorType *ot);
void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot);
void SEQUENCER_OT_select_grouped(struct wmOperatorType *ot);
-/* sequencer_select.c */
+/* sequencer_add.c */
void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot);
@@ -178,11 +168,6 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot);
-enum {
- SEQ_SPLIT_SOFT,
- SEQ_SPLIT_HARD,
-};
-
/* sequencer_ops.c */
void sequencer_operatortypes(void);
void sequencer_keymap(struct wmKeyConfig *keyconf);
@@ -205,6 +190,12 @@ void SEQUENCER_OT_strip_modifier_copy(struct wmOperatorType *ot);
/* sequencer_view.c */
void SEQUENCER_OT_sample(struct wmOperatorType *ot);
+void SEQUENCER_OT_view_all(struct wmOperatorType *ot);
+void SEQUENCER_OT_view_frame(struct wmOperatorType *ot);
+void SEQUENCER_OT_view_all_preview(struct wmOperatorType *ot);
+void SEQUENCER_OT_view_zoom_ratio(struct wmOperatorType *ot);
+void SEQUENCER_OT_view_selected(struct wmOperatorType *ot);
+void SEQUENCER_OT_view_ghost_border(struct wmOperatorType *ot);
/* sequencer_preview.c */
void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq);
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index 4fe1c953c74..0a7aa1a6072 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -74,14 +74,6 @@ void sequencer_operatortypes(void)
WM_operatortype_append(SEQUENCER_OT_copy);
WM_operatortype_append(SEQUENCER_OT_paste);
- WM_operatortype_append(SEQUENCER_OT_view_all);
- WM_operatortype_append(SEQUENCER_OT_view_selected);
- WM_operatortype_append(SEQUENCER_OT_view_frame);
- WM_operatortype_append(SEQUENCER_OT_view_all_preview);
- WM_operatortype_append(SEQUENCER_OT_view_toggle);
- WM_operatortype_append(SEQUENCER_OT_view_zoom_ratio);
- WM_operatortype_append(SEQUENCER_OT_view_ghost_border);
-
WM_operatortype_append(SEQUENCER_OT_rebuild_proxy);
WM_operatortype_append(SEQUENCER_OT_enable_proxies);
WM_operatortype_append(SEQUENCER_OT_change_effect_input);
@@ -120,6 +112,12 @@ void sequencer_operatortypes(void)
/* sequencer_view.h */
WM_operatortype_append(SEQUENCER_OT_sample);
+ WM_operatortype_append(SEQUENCER_OT_view_all);
+ WM_operatortype_append(SEQUENCER_OT_view_frame);
+ WM_operatortype_append(SEQUENCER_OT_view_all_preview);
+ WM_operatortype_append(SEQUENCER_OT_view_zoom_ratio);
+ WM_operatortype_append(SEQUENCER_OT_view_selected);
+ WM_operatortype_append(SEQUENCER_OT_view_ghost_border);
}
void sequencer_keymap(wmKeyConfig *keyconf)
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c
index d397c255b03..f91db3efef4 100644
--- a/source/blender/editors/space_sequencer/sequencer_view.c
+++ b/source/blender/editors/space_sequencer/sequencer_view.c
@@ -21,16 +21,36 @@
* \ingroup spseq
*/
-#include "ED_util_imbuf.h"
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
-#include "RNA_define.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_context.h"
+#include "BKE_sequencer.h"
+#include "WM_api.h"
#include "WM_types.h"
+#include "RNA_define.h"
+
+#include "UI_view2d.h"
+
+#include "RNA_define.h"
+
+/* For menu, popup, icons, etc. */
+#include "ED_anim_api.h"
+#include "ED_screen.h"
+#include "ED_util_imbuf.h"
+
/* Own include. */
#include "sequencer_intern.h"
-/******************** sample backdrop operator ********************/
+/* -------------------------------------------------------------------- */
+/** \name Sequencer Sample Backdrop Operator
+ * \{ */
+
void SEQUENCER_OT_sample(wmOperatorType *ot)
{
/* Identifiers. */
@@ -53,3 +73,333 @@ void SEQUENCER_OT_sample(wmOperatorType *ot)
RNA_def_property_subtype(prop, PROP_PIXEL);
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Sequencer Frame All Operator
+ * \{ */
+
+static int sequencer_view_all_exec(bContext *C, wmOperator *op)
+{
+ ARegion *region = CTX_wm_region(C);
+ rctf box;
+
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+
+ boundbox_seq(CTX_data_scene(C), &box);
+ UI_view2d_smooth_view(C, region, &box, smooth_viewtx);
+ return OPERATOR_FINISHED;
+}
+
+void SEQUENCER_OT_view_all(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Frame All";
+ ot->idname = "SEQUENCER_OT_view_all";
+ ot->description = "View all the strips in the sequencer";
+
+ /* Api callbacks. */
+ ot->exec = sequencer_view_all_exec;
+ ot->poll = ED_operator_sequencer_active;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Go to Current Frame Operator
+ * \{ */
+
+static int sequencer_view_frame_exec(bContext *C, wmOperator *op)
+{
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ ANIM_center_frame(C, smooth_viewtx);
+
+ return OPERATOR_FINISHED;
+}
+
+void SEQUENCER_OT_view_frame(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Go to Current Frame";
+ ot->idname = "SEQUENCER_OT_view_frame";
+ ot->description = "Move the view to the current frame";
+
+ /* Api callbacks. */
+ ot->exec = sequencer_view_frame_exec;
+ ot->poll = ED_operator_sequencer_active;
+
+ /* Flags. */
+ ot->flag = 0;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Preview Frame All Operator
+ * \{ */
+
+static int sequencer_view_all_preview_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *area = CTX_wm_area(C);
+#if 0
+ ARegion *region = CTX_wm_region(C);
+ SpaceSeq *sseq = area->spacedata.first;
+ Scene *scene = CTX_data_scene(C);
+#endif
+ View2D *v2d = UI_view2d_fromcontext(C);
+
+ v2d->cur = v2d->tot;
+ UI_view2d_curRect_validate(v2d);
+ UI_view2d_sync(screen, area, v2d, V2D_LOCK_COPY);
+
+#if 0
+ /* Like zooming on an image view. */
+ float zoomX, zoomY;
+ int width, height, imgwidth, imgheight;
+
+ width = region->winx;
+ height = region->winy;
+
+ seq_reset_imageofs(sseq);
+
+ imgwidth = (scene->r.size * scene->r.xsch) / 100;
+ imgheight = (scene->r.size * scene->r.ysch) / 100;
+
+ /* Apply aspect, doesn't need to be that accurate. */
+ imgwidth = (int)(imgwidth * (scene->r.xasp / scene->r.yasp));
+
+ if (((imgwidth >= width) || (imgheight >= height)) && ((width > 0) && (height > 0))) {
+ /* Find the zoom value that will fit the image in the image space. */
+ zoomX = ((float)width) / ((float)imgwidth);
+ zoomY = ((float)height) / ((float)imgheight);
+ sseq->zoom = (zoomX < zoomY) ? zoomX : zoomY;
+
+ sseq->zoom = 1.0f / power_of_2(1 / min_ff(zoomX, zoomY));
+ }
+ else {
+ sseq->zoom = 1.0f;
+ }
+#endif
+
+ ED_area_tag_redraw(CTX_wm_area(C));
+ return OPERATOR_FINISHED;
+}
+
+void SEQUENCER_OT_view_all_preview(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Frame All";
+ ot->idname = "SEQUENCER_OT_view_all_preview";
+ ot->description = "Zoom preview to fit in the area";
+
+ /* Api callbacks. */
+ ot->exec = sequencer_view_all_preview_exec;
+ ot->poll = ED_operator_sequencer_active;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Sequencer View Zoom Ratio Operator
+ * \{ */
+
+static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
+{
+ RenderData *rd = &CTX_data_scene(C)->r;
+ View2D *v2d = UI_view2d_fromcontext(C);
+
+ float ratio = RNA_float_get(op->ptr, "ratio");
+
+ float winx = (int)(rd->size * rd->xsch) / 100;
+ float winy = (int)(rd->size * rd->ysch) / 100;
+
+ float facx = BLI_rcti_size_x(&v2d->mask) / winx;
+ float facy = BLI_rcti_size_y(&v2d->mask) / winy;
+
+ BLI_rctf_resize(&v2d->cur, ceilf(winx * facx / ratio + 0.5f), ceilf(winy * facy / ratio + 0.5f));
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Sequencer View Zoom Ratio";
+ ot->idname = "SEQUENCER_OT_view_zoom_ratio";
+ ot->description = "Change zoom ratio of sequencer preview";
+
+ /* Api callbacks. */
+ ot->exec = sequencer_view_zoom_ratio_exec;
+ ot->poll = ED_operator_sequencer_active;
+
+ /* Properties. */
+ RNA_def_float(ot->srna,
+ "ratio",
+ 1.0f,
+ -FLT_MAX,
+ FLT_MAX,
+ "Ratio",
+ "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out",
+ -FLT_MAX,
+ FLT_MAX);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Frame Selected Operator
+ * \{ */
+
+static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ View2D *v2d = UI_view2d_fromcontext(C);
+ ARegion *region = CTX_wm_region(C);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *last_seq = BKE_sequencer_active_get(scene);
+ Sequence *seq;
+ rctf cur_new = v2d->cur;
+
+ int xmin = MAXFRAME * 2;
+ int xmax = -MAXFRAME * 2;
+ int ymin = MAXSEQ + 1;
+ int ymax = 0;
+ int orig_height;
+ int ymid;
+ int ymargin = 1;
+ int xmargin = FPS;
+
+ if (ed == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ if ((seq->flag & SELECT) || (seq == last_seq)) {
+ xmin = min_ii(xmin, seq->startdisp);
+ xmax = max_ii(xmax, seq->enddisp);
+
+ ymin = min_ii(ymin, seq->machine);
+ ymax = max_ii(ymax, seq->machine);
+ }
+ }
+
+ if (ymax != 0) {
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+
+ xmax += xmargin;
+ xmin -= xmargin;
+ ymax += ymargin;
+ ymin -= ymargin;
+
+ orig_height = BLI_rctf_size_y(&cur_new);
+
+ cur_new.xmin = xmin;
+ cur_new.xmax = xmax;
+
+ cur_new.ymin = ymin;
+ cur_new.ymax = ymax;
+
+ /* Only zoom out vertically. */
+ if (orig_height > BLI_rctf_size_y(&cur_new)) {
+ ymid = BLI_rctf_cent_y(&cur_new);
+
+ cur_new.ymin = ymid - (orig_height / 2);
+ cur_new.ymax = ymid + (orig_height / 2);
+ }
+
+ UI_view2d_smooth_view(C, region, &cur_new, smooth_viewtx);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void SEQUENCER_OT_view_selected(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Frame Selected";
+ ot->idname = "SEQUENCER_OT_view_selected";
+ ot->description = "Zoom the sequencer on the selected strips";
+
+ /* Api callbacks. */
+ ot->exec = sequencer_view_selected_exec;
+ ot->poll = ED_operator_sequencer_active;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Border Offset View Operator
+ * \{ */
+
+static int view_ghost_border_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ View2D *v2d = UI_view2d_fromcontext(C);
+
+ rctf rect;
+
+ /* Convert coordinates of rect to 'tot' rect coordinates. */
+ WM_operator_properties_border_to_rctf(op, &rect);
+ UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
+
+ rect.xmin /= fabsf(BLI_rctf_size_x(&v2d->tot));
+ rect.ymin /= fabsf(BLI_rctf_size_y(&v2d->tot));
+
+ rect.xmax /= fabsf(BLI_rctf_size_x(&v2d->tot));
+ rect.ymax /= fabsf(BLI_rctf_size_y(&v2d->tot));
+
+ rect.xmin += 0.5f;
+ rect.xmax += 0.5f;
+ rect.ymin += 0.5f;
+ rect.ymax += 0.5f;
+
+ CLAMP(rect.xmin, 0.0f, 1.0f);
+ CLAMP(rect.ymin, 0.0f, 1.0f);
+ CLAMP(rect.xmax, 0.0f, 1.0f);
+ CLAMP(rect.ymax, 0.0f, 1.0f);
+
+ scene->ed->over_border = rect;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Border Offset View";
+ ot->idname = "SEQUENCER_OT_view_ghost_border";
+ ot->description = "Set the boundaries of the border used for offset-view";
+
+ /* Api callbacks. */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = view_ghost_border_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->poll = sequencer_view_preview_poll;
+ ot->cancel = WM_gesture_box_cancel;
+
+ /* Flags. */
+ ot->flag = 0;
+
+ /* Properties. */
+ WM_operator_properties_gesture_box(ot);
+}
+
+/** \} */
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 4a5f8cc1bfe..ddc8394264a 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -209,7 +209,7 @@ typedef struct ImBuf {
*/
float *rect_float;
- /* resolution - pixels per meter */
+ /** Resolution in pixels per meter. Multiply by `0.0254` for DPI. */
double ppm[2];
/* tiled pixel storage */
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 882808cbc14..0555d213b3f 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -390,7 +390,8 @@ static void openexr_header_metadata(Header *header, struct ImBuf *ibuf)
}
if (ibuf->ppm[0] > 0.0) {
- addXDensity(*header, ibuf->ppm[0] / 39.3700787); /* 1 meter = 39.3700787 inches */
+ /* Convert meters to inches. */
+ addXDensity(*header, ibuf->ppm[0] * 0.0254);
}
}
@@ -1920,7 +1921,8 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem,
ibuf->flags |= exr_is_half_float(*file) ? IB_halffloat : 0;
if (hasXDensity(file->header(0))) {
- ibuf->ppm[0] = xDensity(file->header(0)) * 39.3700787f;
+ /* Convert inches to meters. */
+ ibuf->ppm[0] = (double)xDensity(file->header(0)) / 0.0254;
ibuf->ppm[1] = ibuf->ppm[0] * (double)file->header(0).pixelAspectRatio();
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 802780b37f1..482589e2ccb 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -593,6 +593,7 @@ void WM_uilisttype_free(void);
/* wm_menu_type.c */
void WM_menutype_init(void);
struct MenuType *WM_menutype_find(const char *idname, bool quiet);
+void WM_menutype_iter(struct GHashIterator *ghi);
bool WM_menutype_add(struct MenuType *mt);
void WM_menutype_freelink(struct MenuType *mt);
void WM_menutype_free(void);
diff --git a/source/blender/windowmanager/intern/wm_menu_type.c b/source/blender/windowmanager/intern/wm_menu_type.c
index c4491423d82..dc4efe79433 100644
--- a/source/blender/windowmanager/intern/wm_menu_type.c
+++ b/source/blender/windowmanager/intern/wm_menu_type.c
@@ -57,6 +57,11 @@ MenuType *WM_menutype_find(const char *idname, bool quiet)
return NULL;
}
+void WM_menutype_iter(GHashIterator *ghi)
+{
+ BLI_ghashIterator_init(ghi, menutypes_hash);
+}
+
bool WM_menutype_add(MenuType *mt)
{
BLI_assert((mt->description == NULL) || (mt->description[0]));